base
http://hackage.haskell.org/package/base-compat "base-compat package on Hackage"
http://www.haskell.org "The Haskell Programming Language"
https://tldrlegal.com/license/mit-license "MIT License"
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.
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:
.Compat
is
needed.base-compat
: patches are welcomed!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
.
So far the following is covered.
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.<>
bitDefault
, testBitDefault
, and popCountDefault
to Data.Bits.Compat
toIntegralSized
to Data.Bits.Compat
(if using base-4.7
)bool
function to Data.Bool.Compat
isLeft
, isRight
, fromLeft
, and fromRight
to Data.Either.Compat
forkFinally
to Control.Concurrent.Compat
withMVarMasked
function to Control.Concurrent.MVar.Compat
(<$!>)
function to Control.Monad.Compat
RealFloat
constraints on realPart
, imagPart
, conjugate
, mkPolar
,
and cis
in Data.Complex.Compat
maximumBy
/minimumBy
to Data.Foldable.Compat
($>)
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
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
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
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.
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: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: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
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!