# base-compat

A compatibility layer for base

Version on this page: | 0.9.1 |

LTS Haskell 11.10: | 0.9.3 |

Stackage Nightly 2018-05-23: | 0.10.1 |

Latest on Hackage: | 0.10.1 |

#### Module documentation for 0.9.1

- Control
- Control.Concurrent
- Control.Concurrent.Compat
- Control.Concurrent.MVar

- Control.Monad
- Control.Monad.Compat
- Control.Monad.ST
- Control.Monad.ST.Lazy
- Control.Monad.ST.Lazy.Unsafe

- Control.Monad.ST.Unsafe

- Control.Monad.ST.Lazy

- Control.Concurrent
- Data
- Data.Bits
- Data.Bool
- Data.Complex
- Data.Either
- Data.Foldable
- Data.Function
- Data.Functor
- Data.Functor.Compat
- Data.Functor.Const

- Data.IORef
- Data.List
- Data.Monoid
- Data.Ratio
- Data.STRef
- Data.String
- Data.Version
- Data.Word

- Debug
- Debug.Trace

- Foreign
- Foreign.Compat
- Foreign.ForeignPtr
- Foreign.ForeignPtr.Safe
- Foreign.ForeignPtr.Unsafe

- Foreign.Marshal
- Foreign.Marshal.Alloc
- Foreign.Marshal.Array
- Foreign.Marshal.Compat
- Foreign.Marshal.Safe
- Foreign.Marshal.Unsafe
- Foreign.Marshal.Utils

- Numeric
- Prelude
- System
- System.Environment
- System.Exit
- System.IO
- System.IO.Unsafe

- Text
- Text.Read

# A compatibility layer for `base`

[][Haskell.org] [][tl;dr Legal: MIT]

http://hackage.haskell.org/package/base-compat "base-compat package on Hackage" [Haskell.org]: http://www.haskell.org "The Haskell Programming Language" [tl;dr Legal: MIT]: https://tldrlegal.com/license/mit-license "MIT License"

## Scope

The scope of `base-compat`

is to provide functions available in later versions
of base to a wider (older) range of compilers.

In addition, successful library proposals that have been accepted to be part of
upcoming versions of `base`

are also included. This package is not intended to
replace `base`

, but to complement it.

Note that `base-compat`

does not add any orphan instances. There is a separate
package `base-orphans`

for
that.

In addition, `base-compat`

only backports functions. In particular, we
purposefully do not backport data types or type classes introduced in newer
versions of `base`

. For more info, see the
Data types and type classes
section.

`base-compat`

is intentionally designed to have zero dependencies. As a
consequence, there are some modules that can only be backported up to certain
versions of `base`

. If an even wider support window is desired in these
scenarios, there also exists a `base-compat-batteries`

package which augments
`base-compat`

with certain compatibility package dependencies. For more info,
see the Dependencies section.

## Basic usage

In your cabal file, you should have something like this:

```
build-depends: base >= 4.3
, base-compat >= 0.9.0
```

Then, lets say you want to use the `isRight`

function introduced with
`base-4.7.0.0`

. Replace:

`import Data.Either`

with

`import Data.Either.Compat`

*Note (1)*: There is no need to import both unqualified. The `.Compat`

modules
re-exports the original module.

*Note (2)*: If a given module `.Compat`

version is not defined, that either
means that:

- The module has not changed in recent base versions, thus no
`.Compat`

is needed. - The module has changed, but the changes depend on newer versions of GHC, and thus are not portable.
- The module has changed, but those changes have not yet been merged in
`base-compat`

: patches are welcomed!

## Using `Prelude.Compat`

If you want to use `Prelude.Compat`

(which provides all the
AMP/Traversable/Foldable changes from `base-4.8.0.0`

), it's best to hide
`Prelude`

, e.g.:

```
import Prelude ()
import Prelude.Compat
main :: IO ()
main = mapM_ print (Just 23)
```

Alternatively, you can use the `NoImplicitPrelude`

language extension:

```
{-# LANGUAGE NoImplicitPrelude #-}
import Prelude.Compat
main :: IO ()
main = mapM_ print (Just 23)
```

Note that we use

`mapM_ :: (Foldable t, Monad m) => (a -> m b) -> t a -> m ()`

from `Data.Foldable`

here, which is only exposed from `Prelude`

since
`base-4.8.0.0`

.

Using this approach allows you to write code that works seamlessly with all
versions of GHC that are supported by `base-compat`

.

## What is covered

So far the following is covered.

### For compatibility with the latest released version of `base`

`Prelude.Compat`

incorporates the AMP/Foldable/Traversable changes and exposes the same interface as`Prelude`

from`base-4.9.0.0`

`System.IO.Error.catch`

is not re-exported from`Prelude.Compat`

for older versions of`base`

`Text.Read.Compat.readMaybe`

`Text.Read.Compat.readEither`

`Data.Monoid.Compat.<>`

- Added
`bitDefault`

,`testBitDefault`

, and`popCountDefault`

to`Data.Bits.Compat`

- Added
`toIntegralSized`

to`Data.Bits.Compat`

(if using`base-4.7`

) - Added
`bool`

function to`Data.Bool.Compat`

- Added
`isLeft`

,`isRight`

,`fromLeft`

, and`fromRight`

to`Data.Either.Compat`

- Added
`forkFinally`

to`Control.Concurrent.Compat`

- Added
`withMVarMasked`

function to`Control.Concurrent.MVar.Compat`

- Added
`(<$!>)`

function to`Control.Monad.Compat`

- Weakened
`RealFloat`

constraints on`realPart`

,`imagPart`

,`conjugate`

,`mkPolar`

, and`cis`

in`Data.Complex.Compat`

- Added more efficient
`maximumBy`

/`minimumBy`

to`Data.Foldable.Compat`

- Added
`($>)`

and`void`

functions to`Data.Functor.Compat`

`(&)`

function to`Data.Function.Compat`

`($>)`

and`void`

functions to`Data.Functor.Compat`

`modifyIORef'`

,`atomicModifyIORef'`

and`atomicWriteIORef`

to`Data.IORef.Compat`

`dropWhileEnd`

,`isSubsequenceOf`

,`sortOn`

, and`uncons`

functions to`Data.List.Compat`

- Correct versions of
`nub`

,`nubBy`

,`union`

, and`unionBy`

to`Data.List.Compat`

`asProxyTypeOf`

with a generalized type signature to`Data.Proxy.Compat`

`modifySTRef'`

to`Data.STRef.Compat`

`String`

,`lines`

,`words`

,`unlines`

, and`unwords`

to`Data.String.Compat`

`gcoerceWith`

to`Data.Type.Coercion.Compat`

`makeVersion`

function to`Data.Version.Compat`

`traceId`

,`traceShowId`

,`traceM`

, and`traceShowM`

functions to`Debug.Trace.Compat`

`byteSwap16`

,`byteSwap32`

, and`byteSwap64`

to`Data.Word.Compat`

`plusForeignPtr`

to`Foreign.ForeignPtr.Compat`

`calloc`

and`callocBytes`

functions to`Foreign.Marshal.Alloc.Compat`

`callocArray`

and`callocArray0`

functions to`Foreign.Marshal.Array.Compat`

`fillBytes`

to`Foreign.Marshal.Utils.Compat`

- Added
`Data.List.Compat.scanl'`

`showFFloatAlt`

and`showGFloatAlt`

to`Numeric.Compat`

`lookupEnv`

,`setEnv`

and`unsetEnv`

to`System.Environment.Compat`

`unsafeFixIO`

and`unsafeDupablePerformIO`

to`System.IO.Unsafe.IO`

## What is not covered

### Data types and type classes

`base-compat`

purposefully does not export any data types or type classes that
were introduced in more recent versions of `base`

. The main reasoning for this
policy is that it is not some data types and type classes have had their APIs
change in different versions of `base`

, which makes having a consistent
compatibility API for them practically impossible.

As an example, consider the `FiniteBits`

type class. It was introduced in
`base-4.7.0.0`

with the following API:

```
class Bits b => FiniteBits b where
finiteBitSize :: b -> Int
```

However, in `base-4.8.0.0`

,
`FiniteBits`

gained additional functions:

```
class Bits b => FiniteBits b where
finiteBitSize :: b -> Int
countLeadingZeros :: b -> Int -- ^ @since 4.8.0.0
countTrailingZeros :: b -> Int -- ^ @since 4.8.0.0
```

This raises the question: how can `FiniteBits`

be backported consistently
across all versions of `base`

? One approach is to backport the API exposed in
`base-4.8.0.0`

on versions prior to `4.7.0.0`

. The problem with this is that
`countLeadingZeros`

and `countTrailingZeros`

are not exposed in `base-4.7.0.0`

,
so instances of `FiniteBits`

would have to be declared like this:

```
instance FiniteBits Foo where
finiteBitSize = ...
#if MIN_VERSION_base(4,8,0) || !(MIN_VERSION_base(4,7,0))
countLeadingZeros = ...
countTrailingZeros = ...
#endif
```

Another approach is to backport the API from `base-4.7.0.0`

and to declare
additional methods outside of the class:

```
#if MIN_VERSION_base(4,7,0) && !(MIN_VERSION_base(4,8,0))
countLeadingZeros :: FiniteBits b => b -> Int
countLeadingZeros = {- default implementation #-}
#endif
```

The situation is only slightly better for classes which exist across all versions of `base`

,
but have grown their API. For example, it's tempting to define

```
#if !(MIN_VERSION_base(4,8,0))
displayException :: Exception e => e -> String
displayException = show
#endif
```

As with the previous approach, you won't be able to define new members of the type class without CPP guards. In other words, the non-CPP approach would limit uses to the lowest common denominator.

As neither approach is a very satisfactory solution, and to embrace consistency, we do not pursue either approach. For similar reasons, we do not backport data types.

### Dependencies

`base-compat`

is designed to have zero dependencies (besides libraries that
ship with GHC itself). A consequence of this choice is that there are certain
modules that have a "limited" support window. An important example of this is
`Prelude.Compat`

, which backports the `Semigroup`

class to versions of `base`

older than 4.11 (when it was added to the `Prelude`

). Because `Semigroup`

was
not added to `base`

until `base-4.9`

, `base-compat`

cannot backport it to
any earlier version of `base`

than this.

If you would instead desire to be able to use a version of `Prelude.Compat`

that *does* backport `Semigroup`

to even older versions of `base`

, even if it
means pulling in other dependencies, then you are in luck. There also exists
a `base-compat-batteries`

package, which exposes a strict superset of the API
in `base-compat`

. `base-compat-batteries`

has all the same modules as
`base-compat`

, but exposes more functionality on more versions of `base`

by
reexporting things from compatibility libraries whenever necessary. (For
instance, `base-compat-batteries`

exports the `Semigroup`

class from the
`semigroups`

library when built against versions of `base`

older than 4.9.)

Because `base-compat`

and `base-compat-batteries`

have the same module names,
they are quite easy to switch out for one another in library projects, at the
expense of having clashing names if one tries to import them in GHCi. To
work around this issue, `base-compat`

and `base-compat-batteries`

also provide
copies of each module with the suffix `.Repl`

(for `base-compat`

) and
`.Repl.Batteries`

(for `base-compat-batteries`

) to give them globally unique
namespaces in the event one wants to import them into GHCi.

Here is a list of compatibility libraries that `base-compat-batteries`

depends
on, paired with the things that each library backports:

`bifunctors`

for:*The*The`Bifunctor`

type class, introduced in`base-4.8.0.0`

`Bifoldable`

and`Bitraversable`

type classes, introduced in`base-4.10.0.0`

`fail`

for the`MonadFail`

type class, introduced in`base-4.9.0.0`

`nats`

for the`Natural`

data type, introduced in`base-4.8.0.0`

`semigroups`

for the`Semigroup`

typeclass and the`NonEmpty`

,`Min`

,`Max`

,`First`

,`Last`

,`WrappedMonoid`

,`Option`

, and`Arg`

data types, introduced in`base-4.9.0.0`

`tagged`

for the`Proxy`

data type, introduced in`base-4.7.0.0`

`transformers`

for:*The*The`Identity`

data type, introduced in`base-4.8.0.0`

`MonadIO`

type class; and the`Compose`

,`Product`

, and`Sum`

data types, introduced in`base-4.9.0.0`

`void`

for the`Void`

data type, introduced in`base-4.8.0.0`

## Supported versions of GHC/`base`

`ghc-8.4.1`

/`base-4.11.0.0`

`ghc-8.2.2`

/`base-4.10.1.0`

`ghc-8.2.1`

/`base-4.10.0.0`

`ghc-8.0.2`

/`base-4.9.1.0`

`ghc-8.0.1`

/`base-4.9.0.0`

`ghc-7.10.3`

/`base-4.8.2.0`

`ghc-7.10.2`

/`base-4.8.1.0`

`ghc-7.10.1`

/`base-4.8.0.0`

`ghc-7.8.4`

/`base-4.7.0.2`

`ghc-7.8.3`

/`base-4.7.0.1`

`ghc-7.8.2`

/`base-4.7.0.0`

`ghc-7.8.1`

/`base-4.7.0.0`

`ghc-7.6.3`

/`base-4.6.0.1`

`ghc-7.6.2`

/`base-4.6.0.1`

`ghc-7.6.1`

/`base-4.6.0.0`

`ghc-7.4.2`

/`base-4.5.1.0`

`ghc-7.4.1`

/`base-4.5.0.0`

`ghc-7.2.2`

/`base-4.4.1.0`

`ghc-7.2.1`

/`base-4.4.0.0`

`ghc-7.0.4`

/`base-4.3.1.0`

`ghc-7.0.3`

/`base-4.3.1.0`

`ghc-7.0.2`

/`base-4.3.1.0`

`ghc-7.0.1`

/`base-4.3.0.0`

We also make an attempt to keep `base-compat`

building with GHC HEAD, but due
to its volatility, it may not work at any given point in time. If it doesn't,
please report it!

Patches are welcome; add tests for new code!

## Changes

## Changes in 0.10.1 [2018.04.10]

- Add
`Data.List.NonEmpty.Compat`

. - Reexport
`(Data.Semigroup.<>)`

from`Data.Monoid.Compat`

back to`base-4.9`

.

## Changes in 0.10.0 [2018.04.05]

- Sync with
`base-4.11`

/GHC 8.4 Backport

`Semigroup((<>))`

to`Prelude.Compat`

.Note that the

`Semigroup`

class has only been in`base`

since`base-4.9`

/GHC 8.0, so accordingly, this can only be backported back to GHC 8.0. If you wish to have a version of`Prelude.Compat`

that backports`Semigroup`

to older GHCs (by conditionally depending on the`semigroups`

library), use the`Prelude.Compat`

module from the`base-compat-batteries`

package.- Backport
`(<&>)`

to`Data.Functor.Compat`

- Backport
`iterate'`

to`Data.List.Compat`

- Backport
`showHFloat`

to`Numeric.Compat`

- Backport a
`RuntimeRep`

-polymorphic`withTypeable`

function to`Type.Reflection.Compat`

. (This is only exported on`base-4.10`

/GHC 8.2.) - Introduce the following modules, back until the oldest version of
`base`

that can support backporting them. If you wish to use them in conjunction with older versions of`base`

, use the`base-compat-batteries`

package. -`Control.Monad.Fail.Compat`

(back until`base-4.9`

/GHC 8.0) -`Control.Monad.IO.Class.Compat`

(back until`base-4.9`

/GHC 8.0) -`Data.Bifunctor`

(back until`base-4.8`

/GHC 7.10) -`Data.Bifoldable`

and`Data.Bitraversable`

(back until`base-4.10`

/GHC 8.2) -`Data.Functor.Compose.Compat`

,`Data.Functor.Product.Compat`

, and`Data.Functor.Sum.Compat`

(back until`base-4.9`

/GHC 8.0) -`Data.Functor.Identity.Compat`

(back until`base-4.8`

/GHC 7.10) -`Data.Semigroup.Compat`

(back until`base-4.9`

/GHC 8.0) -`Data.Void.Compat`

(back until`base-4.8`

/GHC 7.10) -`Numeric.Natural.Compat`

(back until`base-4.8`

/GHC 7.10) - Introduce versions of modules with the suffix
`.Repl`

. These simply reexport the contents of their counterparts without the`.Repl`

suffix to provide a globally unique namespace to import from in the event one wants to import`base-compat`

modules into GHCi. (In`base-compat-batteries`

, the corresponding suffix is`.Repl.Batteries`

.)

## Changes in 0.9.3 [2017.04.10]

- Sync with
`base-4.10`

/GHC 8.2 - Backport
`fromLeft`

/`fromRight`

to`Data.Either.Compat`

- Backport implementations of
`maximumBy`

/`minimumBy`

which use constant stack space to`Data.Foldable.Compat`

- Backport
`asProxyTypeOf`

with a generalized type signature to`Data.Proxy.Compat`

- Backport
`gcoerceWith`

to`Data.Type.Coercion.Compat`

- Backport
`plusForeignPtr`

to`Foreign.ForeignPtr.Compat`

## Changes in 0.9.2

Allow building on the HaLVM

## Changes in 0.9.1

Use the more efficient version of

`replicateM`

and`replicateM_`

introduced in`base-4.9`

## Changes in 0.9.0

- Sync with
`base-4.9`

/GHC 8.0 - Weakened
`RealFloat`

constraints on`realPart`

,`imagPart`

,`conjugate`

,`mkPolar`

, and`cis`

in`Data.Complex.Compat`

- Backport
`Foreign.ForeignPtr.Safe`

and`Foreign.Marshal.Safe`

- Generalize
`filterM`

,`forever`

,`mapAndUnzipM`

,`zipWithM`

,`zipWithM_`

,`replicateM`

, and`replicateM_`

in`Control.Monad`

from`Monad`

to`Applicative`

- Backport
`.Unsafe.Compat`

modules (for`Control.Monad.ST`

,`Control.Monad.ST.Lazy`

,`Foreign.ForeignPtr`

, and`Foreign.Marshal`

) - Backport
`forkFinally`

and`forkOSWithUnmask`

to`Control.Concurrent.Compat`

- Backport
`Data.Functor.Const`

- Backport
`modifyIORef'`

,`atomicModifyIORef'`

and`atomicWriteIORef`

to`Data.IORef.Compat`

`Data.Ratio.{denominator,numerator}`

have no`Integral`

constraint anymore- Backport
`modifySTRef'`

to`Data.STRef.Compat`

- Export
`String`

,`lines`

,`words`

,`unlines`

, and`unwords`

to`Data.String.Compat`

- Generalize
`Debug.Trace.{traceM, traceShowM}`

from`Monad`

to`Applicative`

- Backport
`errorWithoutStackTrace`

to`Prelude.Compat`

- Backport
`unsafeFixIO`

and`unsafeDupablePerformIO`

to`System.IO.Unsafe.Compat`

## Changes in 0.8.2

- Backport
`bitDefault`

,`testBitDefault`

, and`popCountDefault`

in`Data.Bits.Compat`

to all versions of`base`

- Backport`toIntegralSized`

to`base-4.7`

- Backport
`nub`

and`nubBy`

(as well as`union`

and`unionBy`

, which are implemented in terms of them) to fix logic error in`Data.List.Compat`

- Backport
`byteSwap16`

,`byteSwap32`

, and`byteSwap64`

to`Data.Word.Compat`

- Backport
`fillBytes`

in`Foreign.Marshal.Utils.Compat`

- Backport
`showFFloatAlt`

and`showGFloatAlt`

to`Numeric.Compat`

## Changes in 0.8.1.1

Fixed Windows build

## Changes in 0.8.1

- Implement
`setEnv`

and`unsetEnv`

in`System.Environment.Compat`

(which were ported from the`setenv`

package). As a result,`base-compat`

now depends on`unix`

on POSIX-like operating systems. - Drop GHC 6.12 (and
`base-4.2.0.0`

) compatibility

## Changes in 0.8.0.1

Retrospective version bump updating the changelog to reflect the changes made in 0.8.0

## Changes 0.8.0

- All orphan instances were split off into a separate package,
`base-orphans`

`base-compat`

no longer redefines the data types`Down`

and`Alt`

. See here for the discussion that led to this change.- Update
`Control.Monad.Compat`

for`base-4.8.0.0`

- Update
`Data.List.Compat`

for`base-4.8.0.0`

- Update
`Data.Foldable.Compat`

for`base-4.8.0.0`

## Changes in 0.7.1

- Backported
`Alt`

to`Data.Monoid.Compat`

- Backported
`Down`

to`Data.Ord.Compat`

## Changes in 0.7.0

Add functions and orphan instances introduced by changes to

`base-4.7.0.0`

and`base-4.8.0.0`

## Changes in 0.6.0

Update

`Prelude.Compat`

for`base-4.8.0.0`

and AMP

## Changes in 0.5.0

- Remove Control.Exception.Base.Compat and GHC.Exception.Compat
- Add System.Exit.Compat.die
- Compatibility with base-4.7.1

## Changes in 0.4.1

Add

`setEnv`

and`unsetEnv`

to`System.Environment.Compat`

## Changes in 0.4.0

- Major refactoring: base-compat no longer aims to replace all base, only new code is included in module .Compat
- Removed stubbed modules
- Removed generation scripts

## Changes in 0.3

- Added functions from Base 4.7 (bool, isLeft, isRight)
- Added instances from Base 4.7 (Either Foldable, Traversable,...)

## Changes in 0.2.1

Fix build on windows

## Changes in 0.2.0

- Re-export everything from base
- provides access to
`VERSION_base`

and`MIN_VERSION_base`

CPP macros (with`#include "base-compat.h"`

) - Do not re-export
`System.IO.Error.catch`

from`Prelude`

for`base`

< 4.6.0 - Add
`Eq`

/`Ord`

instance for`ErrorCall`

- Remove
`GHC.IOBase`

,`GHC.Handle`

,`Control.Concurrent.QSem`

,`Control.Concurrent.QSemN`

,`Control.Concurrent.SampleVar`

,`Data.HashTable`

## Changes in 0.1.0

- Remove getExecutablePath, it did not work with GHC < 7.2 (patches welcome!)
- Add
`<>`

**and many more**