# base-compat

A compatibility layer for base

Version on this page: | 0.8.2 |

LTS Haskell 11.1: | 0.9.3 |

Stackage Nightly 2018-03-23: | 0.9.3 |

Latest on Hackage: | 0.9.3 |

#### Module documentation for 0.8.2

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

- Control.Monad

- Control.Concurrent
- Data
- Data.Bits
- Data.Bool
- Data.Either
- Data.Foldable
- Data.Function
- Data.Functor
- Data.List
- Data.Monoid
- Data.Version
- Data.Word

- Debug
- Debug.Trace

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

- Numeric
- Prelude
- System
- System.Environment
- System.Exit

- 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.

## 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
countTrailingZeros :: b -> Int
```

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
```

This is a very unsatisfactory solution, and for this reason, we do not pursue it. For similar reasons, we do not backport data types.

### Other compatibility packages

If you *really* need your favorite data type or type class in `base`

to be
backported, you might be in luck, since several data types have their own
compatibility packages on Hackage. Here is a list of such packages:

`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`

`generic-deriving`

for everything in the`GHC.Generics`

module, introduced to`ghc-prim`

in GHC 7.2 (and later moved to`base-4.6.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`

,`Eq1`

,`Eq2`

,`Ord1`

,`Ord2`

,`Read1`

,`Read2`

,`Show1`

, and`Show2`

typeclasses; 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.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.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**