Hello community, here is the log from the commit of package ghc-base-compat for openSUSE:Factory checked in at 2016-01-28 17:23:32 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ghc-base-compat (Old) and /work/SRC/openSUSE:Factory/.ghc-base-compat.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ghc-base-compat" Changes: -------- --- /work/SRC/openSUSE:Factory/ghc-base-compat/ghc-base-compat.changes 2015-12-24 12:16:19.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.ghc-base-compat.new/ghc-base-compat.changes 2016-01-28 17:24:29.000000000 +0100 @@ -1,0 +2,22 @@ +Wed Jan 20 08:43:57 UTC 2016 - [email protected] + +- update to 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 + +------------------------------------------------------------------- Old: ---- base-compat-0.8.2.tar.gz New: ---- base-compat-0.9.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ghc-base-compat.spec ++++++ --- /var/tmp/diff_new_pack.uAgpB6/_old 2016-01-28 17:24:29.000000000 +0100 +++ /var/tmp/diff_new_pack.uAgpB6/_new 2016-01-28 17:24:29.000000000 +0100 @@ -20,7 +20,7 @@ %bcond_with tests Name: ghc-base-compat -Version: 0.8.2 +Version: 0.9.0 Release: 0 Summary: A compatibility layer for base Group: System/Libraries ++++++ base-compat-0.8.2.tar.gz -> base-compat-0.9.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base-compat-0.8.2/CHANGES.markdown new/base-compat-0.9.0/CHANGES.markdown --- old/base-compat-0.8.2/CHANGES.markdown 2015-05-13 08:36:37.000000000 +0200 +++ new/base-compat-0.9.0/CHANGES.markdown 2016-01-15 03:45:49.000000000 +0100 @@ -1,3 +1,26 @@ +## 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` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base-compat-0.8.2/LICENSE new/base-compat-0.9.0/LICENSE --- old/base-compat-0.8.2/LICENSE 2015-05-13 08:36:37.000000000 +0200 +++ new/base-compat-0.9.0/LICENSE 2016-01-15 03:45:49.000000000 +0100 @@ -1,4 +1,4 @@ -Copyright (c) 2012-2015 Simon Hengel <[email protected]> and Ryan Scott <[email protected]> +Copyright (c) 2012-2015 Simon Hengel <[email protected]> and Ryan Scott <[email protected]> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base-compat-0.8.2/README.markdown new/base-compat-0.9.0/README.markdown --- old/base-compat-0.8.2/README.markdown 2015-05-13 08:36:37.000000000 +0200 +++ new/base-compat-0.9.0/README.markdown 2016-01-15 03:45:49.000000000 +0100 @@ -1,4 +1,20 @@ -# A compatibility layer for `base` [](http://hackage.haskell.org/package/base-compat) [](https://travis-ci.org/haskell-compat/base-compat) +# A compatibility layer for `base` +[][Hackage: base-compat] +[](http://packdeps.haskellers.com/reverse/base-compat) +[][Haskell.org] +[][tl;dr Legal: MIT] +[](https://travis-ci.org/haskell-compat/base-compat) + +[Hackage: base-compat]: + 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 @@ -12,13 +28,19 @@ package [`base-orphans`](https://github.com/haskell-compat/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](#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.8.0 + , base-compat >= 0.9.0 ``` Then, lets say you want to use the `isRight` function introduced with @@ -83,7 +105,7 @@ ### 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.8.0.0` + 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` @@ -93,13 +115,19 @@ * Added `toIntegralSized` to `Data.Bits.Compat` (if using `base-4.7`) * Added `bool` function to `Data.Bool.Compat` * Added `isLeft` and `isRight` 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 `($>)` 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` + * `modifySTRef'` to `Data.STRef.Compat` + * `String`, `lines`, `words`, `unlines`, and `unwords` to `Data.String.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` @@ -109,9 +137,114 @@ * 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`](http://hackage.haskell.org/package/base-4.7.0.0/docs/Data-Bits.html#t:FiniteBits) +with the following API: + +```haskell +class Bits b => FiniteBits b where + finiteBitSize :: b -> Int +``` -## Supported versions of GHC/base +However, in [`base-4.8.0.0`](http://hackage.haskell.org/package/base-4.8.0.0/docs/Data-Bits.html#t:FiniteBits), +`FiniteBits` gained additional functions: + +```haskell +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: + +```haskell +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`](http://hackage.haskell.org/package/bifunctors) + for the [`Bifunctor`](http://hackage.haskell.org/package/base-4.8.0.0/docs/Data-Bifunctor.html#t:Bifunctor) + type class, introduced in `base-4.8.0.0` +* [`generic-deriving`](http://hackage.haskell.org/package/generic-deriving) + for everything in the [`GHC.Generics`](http://hackage.haskell.org/package/base-4.8.0.0/docs/GHC-Generics.html) + module, introduced to `ghc-prim` in GHC 7.2 (and later moved to `base-4.6.0.0`) +* [`nats`](http://hackage.haskell.org/package/nats) + for the [`Natural`](http://hackage.haskell.org/package/base-4.8.0.0/docs/Numeric-Natural.html) + data type, introduced in `base-4.8.0.0` +* [`semigroups`](http://hackage.haskell.org/package/semigroups) + for the [`Semigroup`](http://hackage.haskell.org/package/base-4.9.0.0/docs/Data-Semigroup.html#t:Semigroup) + typeclass and the + [`NonEmpty`](http://hackage.haskell.org/package/base-4.9.0.0/docs/Data-List-NonEmpty.html#t:NonEmpty), + [`Min`](http://hackage.haskell.org/package/base-4.9.0.0/docs/Data-Semigroup.html#t:Min), + [`Max`](http://hackage.haskell.org/package/base-4.9.0.0/docs/Data-Semigroup.html#t:Max), + [`First`](http://hackage.haskell.org/package/base-4.9.0.0/docs/Data-Semigroup.html#t:First), + [`Last`](http://hackage.haskell.org/package/base-4.9.0.0/docs/Data-Semigroup.html#t:Last), + [`WrappedMonoid`](http://hackage.haskell.org/package/base-4.9.0.0/docs/Data-Semigroup.html#t:WrappedMonoid), + [`Option`](http://hackage.haskell.org/package/base-4.9.0.0/docs/Data-Semigroup.html#t:Option), + and + [`Arg`](http://hackage.haskell.org/package/base-4.9.0.0/docs/Data-Semigroup.html#t:Arg) + data types, introduced in `base-4.9.0.0` +* [`tagged`](http://hackage.haskell.org/package/tagged) + for the [`Proxy`](http://hackage.haskell.org/package/base-4.7.0.0/docs/Data-Proxy.html#t:Proxy) + data type, introduced in `base-4.7.0.0` +* [`transformers`](http://hackage.haskell.org/package/transformers) + for: + * The [`Identity`](http://hackage.haskell.org/package/base-4.8.0.0/docs/Data-Functor-Identity.html#t:Identity) + data type, introduced in `base-4.8.0.0` + * The [`MonadIO`](http://hackage.haskell.org/package/base-4.9.0.0/docs/Control-Monad-IO-Class.html#t:MonadIO), + [`Eq1`](http://hackage.haskell.org/package/base-4.9.0.0/docs/Data-Functor-Classes.html#t:Eq1), + [`Eq2`](http://hackage.haskell.org/package/base-4.9.0.0/docs/Data-Functor-Classes.html#t:Eq2), + [`Ord1`](http://hackage.haskell.org/package/base-4.9.0.0/docs/Data-Functor-Classes.html#t:Ord1), + [`Ord2`](http://hackage.haskell.org/package/base-4.9.0.0/docs/Data-Functor-Classes.html#t:Ord2), + [`Read1`](http://hackage.haskell.org/package/base-4.9.0.0/docs/Data-Functor-Classes.html#t:Read1), + [`Read2`](http://hackage.haskell.org/package/base-4.9.0.0/docs/Data-Functor-Classes.html#t:Read2), + [`Show1`](http://hackage.haskell.org/package/base-4.9.0.0/docs/Data-Functor-Classes.html#t:Show1), + and + [`Show2`](http://hackage.haskell.org/package/base-4.9.0.0/docs/Data-Functor-Classes.html#t:Show2) + typeclasses; and the + [`Compose`](http://hackage.haskell.org/package/base-4.9.0.0/docs/Data-Functor-Compose.html#t:Compose), + [`Product`](http://hackage.haskell.org/package/base-4.9.0.0/docs/Data-Functor-Product.html#t:Product), + and + [`Sum`](http://hackage.haskell.org/package/base-4.9.0.0/docs/Data-Functor-Sum.html#t:Sum) + data types, introduced in `base-4.9.0.0` +* [`void`](http://hackage.haskell.org/package/void) + for the [`Void`](http://hackage.haskell.org/package/base-4.8.0.0/docs/Data-Void.html#t:Void) + data type, introduced in `base-4.8.0.0` + +## Supported versions of GHC/`base` + + * `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` @@ -129,16 +262,8 @@ * `ghc-7.0.2` / `base-4.3.1.0` * `ghc-7.0.1` / `base-4.3.0.0` -Patches are welcome; add tests for new code! - -## Development +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! -For `Prelude.Compat` there is an `Prelude.index` file that was generated from -the output of - - ghc --show-iface Prelude.hi - -To verify that `Prelude.Compat` matches the specification given in -`Prelude.types` run: - - ./check-Prelude.sh +Patches are welcome; add tests for new code! diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base-compat-0.8.2/base-compat.cabal new/base-compat-0.9.0/base-compat.cabal --- old/base-compat-0.8.2/base-compat.cabal 2015-05-13 08:36:37.000000000 +0200 +++ new/base-compat-0.9.0/base-compat.cabal 2016-01-15 03:45:49.000000000 +0100 @@ -1,5 +1,5 @@ name: base-compat -version: 0.8.2 +version: 0.9.0 license: MIT license-file: LICENSE copyright: (c) 2012-2015 Simon Hengel, @@ -7,10 +7,10 @@ (c) 2015 Ryan Scott author: Simon Hengel <[email protected]>, João Cristóvão <[email protected]>, - Ryan Scott <[email protected]> + Ryan Scott <[email protected]> maintainer: Simon Hengel <[email protected]>, João Cristóvão <[email protected]>, - Ryan Scott <[email protected]> + Ryan Scott <[email protected]> build-type: Simple cabal-version: >= 1.8 category: Compatibility @@ -24,9 +24,20 @@ for recent changes. . Note that @base-compat@ does not add any orphan instances. - There is a separate package - @<http://hackage.haskell.org/package/base-orphans base-orphans>@ + There is a separate package, + @<http://hackage.haskell.org/package/base-orphans base-orphans>@, for that. + . + In addition, `base-compat` does not backport any data types + or type classes. See + @<https://github.com/haskell-compat/base-compat#data-types-and-type-classes this section of the README>@ + for more info. +tested-with: GHC == 7.0.1, GHC == 7.0.2, GHC == 7.0.3, GHC == 7.0.4 + , GHC == 7.2.1, GHC == 7.2.2 + , GHC == 7.4.1, GHC == 7.4.2 + , GHC == 7.6.1, GHC == 7.6.2, GHC == 7.6.3 + , GHC == 7.8.1, GHC == 7.8.2, GHC == 7.8.3, GHC == 7.8.4 + , GHC == 7.10.1, GHC == 7.10.2, GHC == 7.10.3 extra-source-files: CHANGES.markdown, README.markdown source-repository head @@ -47,28 +58,42 @@ src exposed-modules: + Control.Concurrent.Compat Control.Concurrent.MVar.Compat Control.Monad.Compat + Control.Monad.ST.Lazy.Unsafe.Compat + Control.Monad.ST.Unsafe.Compat Data.Bits.Compat Data.Bool.Compat + Data.Complex.Compat Data.Either.Compat Data.Foldable.Compat Data.Function.Compat Data.Functor.Compat + Data.Functor.Const.Compat + Data.IORef.Compat Data.List.Compat Data.Monoid.Compat + Data.Ratio.Compat + Data.STRef.Compat + Data.String.Compat Data.Version.Compat Data.Word.Compat Debug.Trace.Compat Foreign.Compat + Foreign.ForeignPtr.Safe.Compat + Foreign.ForeignPtr.Unsafe.Compat Foreign.Marshal.Alloc.Compat Foreign.Marshal.Array.Compat Foreign.Marshal.Compat + Foreign.Marshal.Safe.Compat + Foreign.Marshal.Unsafe.Compat Foreign.Marshal.Utils.Compat Numeric.Compat Prelude.Compat System.Environment.Compat System.Exit.Compat + System.IO.Unsafe.Compat Text.Read.Compat test-suite spec @@ -80,6 +105,24 @@ test main-is: Spec.hs + other-modules: + Control.Monad.CompatSpec + Data.Bits.CompatSpec + Data.Bool.CompatSpec + Data.Either.CompatSpec + Data.Function.CompatSpec + Data.Functor.CompatSpec + Data.IORef.CompatSpec + Data.List.CompatSpec + Data.Monoid.CompatSpec + Data.STRef.CompatSpec + Data.Version.CompatSpec + Data.Word.CompatSpec + Foreign.Marshal.Alloc.CompatSpec + Foreign.Marshal.Utils.CompatSpec + Numeric.CompatSpec + System.Environment.CompatSpec + Text.Read.CompatSpec build-depends: base >= 4.3 && < 5 , base-compat diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base-compat-0.8.2/src/Control/Concurrent/Compat.hs new/base-compat-0.9.0/src/Control/Concurrent/Compat.hs --- old/base-compat-0.8.2/src/Control/Concurrent/Compat.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/base-compat-0.9.0/src/Control/Concurrent/Compat.hs 2016-01-15 03:45:49.000000000 +0100 @@ -0,0 +1,44 @@ +{-# LANGUAGE CPP, NoImplicitPrelude #-} +{-# LANGUAGE RankNTypes #-} +module Control.Concurrent.Compat ( + module Base +, forkFinally +, forkOSWithUnmask +) where + +import Control.Concurrent as Base + +#if !(MIN_VERSION_base(4,6,0)) +import Control.Exception +#endif + +#if !(MIN_VERSION_base(4,9,0)) +import GHC.IO (unsafeUnmask) +import Prelude +#endif + +#if !(MIN_VERSION_base(4,6,0)) +-- | fork a thread and call the supplied function when the thread is about +-- to terminate, with an exception or a returned value. The function is +-- called with asynchronous exceptions masked. +-- +-- > forkFinally action and_then = +-- > mask $ \restore -> +-- > forkIO $ try (restore action) >>= and_then +-- +-- This function is useful for informing the parent when a child +-- terminates, for example. +-- +-- /Since: 4.6.0.0/ +forkFinally :: IO a -> (Either SomeException a -> IO ()) -> IO ThreadId +forkFinally action and_then = + mask $ \restore -> + forkIO $ try (restore action) >>= and_then +#endif + +#if !(MIN_VERSION_base(4,9,0)) +-- | Like 'forkIOWithUnmask', but the child thread is a bound thread, +-- as with 'forkOS'. +forkOSWithUnmask :: ((forall a . IO a -> IO a) -> IO ()) -> IO ThreadId +forkOSWithUnmask io = forkOS (io unsafeUnmask) +#endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base-compat-0.8.2/src/Control/Monad/Compat.hs new/base-compat-0.9.0/src/Control/Monad/Compat.hs --- old/base-compat-0.8.2/src/Control/Monad/Compat.hs 2015-05-13 08:36:37.000000000 +0200 +++ new/base-compat-0.9.0/src/Control/Monad/Compat.hs 2016-01-15 03:45:49.000000000 +0100 @@ -19,13 +19,30 @@ , (<$!>) #endif +#if !(MIN_VERSION_base(4,9,0)) +, forever +, filterM +, mapAndUnzipM +, zipWithM +, zipWithM_ +, replicateM +, replicateM_ +#endif ) where -#if MIN_VERSION_base(4,8,0) +#if MIN_VERSION_base(4,9,0) import Control.Monad as Base #else import Control.Monad as Base hiding ( - foldM + forever + , filterM + , mapAndUnzipM + , zipWithM + , zipWithM_ + , replicateM + , replicateM_ +# if !(MIN_VERSION_base(4,8,0)) + , foldM , foldM_ , forM , forM_ @@ -37,8 +54,9 @@ , sequence_ , unless , when +# endif ) -import Control.Applicative (Alternative(..)) +import Control.Applicative import Data.Foldable.Compat import Data.Traversable import Prelude.Compat @@ -116,3 +134,51 @@ let z = f x z `seq` return z #endif + +#if !(MIN_VERSION_base(4,9,0)) +-- | @'forever' act@ repeats the action infinitely. +forever :: (Applicative f) => f a -> f b +{-# INLINE forever #-} +forever a = let a' = a *> a' in a' +-- Use explicit sharing here, as it is prevents a space leak regardless of +-- optimizations. + +-- | This generalizes the list-based 'filter' function. +{-# INLINE filterM #-} +filterM :: (Applicative m) => (a -> m Bool) -> [a] -> m [a] +filterM p = foldr (\ x -> liftA2 (\ flg -> if flg then (x:) else id) (p x)) (pure []) + +-- | The 'mapAndUnzipM' function maps its first argument over a list, returning +-- the result as a pair of lists. This function is mainly used with complicated +-- data structures or a state-transforming monad. +mapAndUnzipM :: (Applicative m) => (a -> m (b,c)) -> [a] -> m ([b], [c]) +{-# INLINE mapAndUnzipM #-} +mapAndUnzipM f xs = unzip <$> traverse f xs + +-- | The 'zipWithM' function generalizes 'zipWith' to arbitrary applicative functors. +zipWithM :: (Applicative m) => (a -> b -> m c) -> [a] -> [b] -> m [c] +{-# INLINE zipWithM #-} +zipWithM f xs ys = sequenceA (zipWith f xs ys) + +-- | 'zipWithM_' is the extension of 'zipWithM' which ignores the final result. +zipWithM_ :: (Applicative m) => (a -> b -> m c) -> [a] -> [b] -> m () +{-# INLINE zipWithM_ #-} +zipWithM_ f xs ys = sequenceA_ (zipWith f xs ys) + +-- | @'replicateM' n act@ performs the action @n@ times, +-- gathering the results. +replicateM :: (Applicative m) => Int -> m a -> m [a] +{-# INLINEABLE replicateM #-} +{-# SPECIALISE replicateM :: Int -> IO a -> IO [a] #-} +{-# SPECIALISE replicateM :: Int -> Maybe a -> Maybe [a] #-} +replicateM 0 _ = pure [] +replicateM n x = liftA2 (:) x (replicateM (pred n) x) + +-- | Like 'replicateM', but discards the result. +replicateM_ :: (Applicative m) => Int -> m a -> m () +{-# INLINEABLE replicateM_ #-} +{-# SPECIALISE replicateM_ :: Int -> IO a -> IO () #-} +{-# SPECIALISE replicateM_ :: Int -> Maybe a -> Maybe () #-} +replicateM_ 0 _ = pure () +replicateM_ n x = x *> replicateM_ (pred n) x +#endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base-compat-0.8.2/src/Control/Monad/ST/Lazy/Unsafe/Compat.hs new/base-compat-0.9.0/src/Control/Monad/ST/Lazy/Unsafe/Compat.hs --- old/base-compat-0.8.2/src/Control/Monad/ST/Lazy/Unsafe/Compat.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/base-compat-0.9.0/src/Control/Monad/ST/Lazy/Unsafe/Compat.hs 2016-01-15 03:45:49.000000000 +0100 @@ -0,0 +1,12 @@ +{-# LANGUAGE CPP, NoImplicitPrelude #-} +module Control.Monad.ST.Lazy.Unsafe.Compat ( + -- * Unsafe operations + unsafeInterleaveST +, unsafeIOToST +) where + +#if MIN_VERSION_base(4,6,0) +import Control.Monad.ST.Lazy.Unsafe (unsafeInterleaveST, unsafeIOToST) +#else +import Control.Monad.ST.Lazy (unsafeInterleaveST, unsafeIOToST) +#endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base-compat-0.8.2/src/Control/Monad/ST/Unsafe/Compat.hs new/base-compat-0.9.0/src/Control/Monad/ST/Unsafe/Compat.hs --- old/base-compat-0.8.2/src/Control/Monad/ST/Unsafe/Compat.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/base-compat-0.9.0/src/Control/Monad/ST/Unsafe/Compat.hs 2016-01-15 03:45:49.000000000 +0100 @@ -0,0 +1,13 @@ +{-# LANGUAGE CPP, NoImplicitPrelude #-} +module Control.Monad.ST.Unsafe.Compat ( + -- * Unsafe operations + unsafeInterleaveST +, unsafeIOToST +, unsafeSTToIO +) where + +#if MIN_VERSION_base(4,6,0) +import Control.Monad.ST.Unsafe (unsafeInterleaveST, unsafeIOToST, unsafeSTToIO) +#else +import Control.Monad.ST (unsafeInterleaveST, unsafeIOToST, unsafeSTToIO) +#endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base-compat-0.8.2/src/Data/Complex/Compat.hs new/base-compat-0.9.0/src/Data/Complex/Compat.hs --- old/base-compat-0.8.2/src/Data/Complex/Compat.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/base-compat-0.9.0/src/Data/Complex/Compat.hs 2016-01-15 03:45:49.000000000 +0100 @@ -0,0 +1,50 @@ +{-# LANGUAGE CPP, NoImplicitPrelude #-} +module Data.Complex.Compat ( + module Base +#if MIN_VERSION_base(4,4,0) && !(MIN_VERSION_base(4,8,0)) +, realPart +, imagPart +, mkPolar +, cis +, conjugate +#endif +) where + +#if !(MIN_VERSION_base(4,4,0)) || MIN_VERSION_base(4,8,0) +import Data.Complex as Base +#else +import Data.Complex as Base hiding ( + realPart + , imagPart + , mkPolar + , cis + , conjugate + ) +import Prelude +#endif + +#if MIN_VERSION_base(4,4,0) && !(MIN_VERSION_base(4,8,0)) +-- | Extracts the real part of a complex number. +realPart :: Complex a -> a +realPart (x :+ _) = x + +-- | Extracts the imaginary part of a complex number. +imagPart :: Complex a -> a +imagPart (_ :+ y) = y + +-- | The conjugate of a complex number. +{-# SPECIALISE conjugate :: Complex Double -> Complex Double #-} +conjugate :: Num a => Complex a -> Complex a +conjugate (x:+y) = x :+ (-y) + +-- | Form a complex number from polar components of magnitude and phase. +{-# SPECIALISE mkPolar :: Double -> Double -> Complex Double #-} +mkPolar :: Floating a => a -> a -> Complex a +mkPolar r theta = r * cos theta :+ r * sin theta + +-- | @'cis' t@ is a complex value with magnitude @1@ +-- and phase @t@ (modulo @2*'pi'@). +{-# SPECIALISE cis :: Double -> Complex Double #-} +cis :: Floating a => a -> Complex a +cis theta = cos theta :+ sin theta +#endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base-compat-0.8.2/src/Data/Functor/Const/Compat.hs new/base-compat-0.9.0/src/Data/Functor/Const/Compat.hs --- old/base-compat-0.8.2/src/Data/Functor/Const/Compat.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/base-compat-0.9.0/src/Data/Functor/Const/Compat.hs 2016-01-15 03:45:49.000000000 +0100 @@ -0,0 +1,4 @@ +{-# LANGUAGE CPP, NoImplicitPrelude #-} +module Data.Functor.Const.Compat (Const(..)) where + +import Control.Applicative (Const(..)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base-compat-0.8.2/src/Data/IORef/Compat.hs new/base-compat-0.9.0/src/Data/IORef/Compat.hs --- old/base-compat-0.8.2/src/Data/IORef/Compat.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/base-compat-0.9.0/src/Data/IORef/Compat.hs 2016-01-15 03:45:49.000000000 +0100 @@ -0,0 +1,42 @@ +{-# LANGUAGE CPP, NoImplicitPrelude #-} +module Data.IORef.Compat ( + module Base +, modifyIORef' +, atomicModifyIORef' +, atomicWriteIORef +) where + +import Data.IORef as Base + +#if !(MIN_VERSION_base(4,6,0)) +import Prelude + +-- |Strict version of 'modifyIORef' +-- +-- /Since: 4.6.0.0/ +modifyIORef' :: IORef a -> (a -> a) -> IO () +modifyIORef' ref f = do + x <- readIORef ref + let x' = f x + x' `seq` writeIORef ref x' + +-- | Strict version of 'atomicModifyIORef'. This forces both the value stored +-- in the 'IORef' as well as the value returned. +-- +-- /Since: 4.6.0.0/ +atomicModifyIORef' :: IORef a -> (a -> (a,b)) -> IO b +atomicModifyIORef' ref f = do + b <- atomicModifyIORef ref $ \a -> + case f a of + v@(a',_) -> a' `seq` v + b `seq` return b + +-- | Variant of 'writeIORef' with the \"barrier to reordering\" property that +-- 'atomicModifyIORef' has. +-- +-- /Since: 4.6.0.0/ +atomicWriteIORef :: IORef a -> a -> IO () +atomicWriteIORef ref a = do + x <- atomicModifyIORef ref (\_ -> (a, ())) + x `seq` return () +#endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base-compat-0.8.2/src/Data/Ratio/Compat.hs new/base-compat-0.9.0/src/Data/Ratio/Compat.hs --- old/base-compat-0.8.2/src/Data/Ratio/Compat.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/base-compat-0.9.0/src/Data/Ratio/Compat.hs 2016-01-15 03:45:49.000000000 +0100 @@ -0,0 +1,32 @@ +{-# LANGUAGE CPP, NoImplicitPrelude #-} +module Data.Ratio.Compat ( + module Base +#if MIN_VERSION_base(4,4,0) && !(MIN_VERSION_base(4,9,0)) +, denominator +, numerator +#endif +) where + +#if !(MIN_VERSION_base(4,4,0)) || MIN_VERSION_base(4,9,0) +import Data.Ratio as Base +#else +import Data.Ratio as Base hiding ( + denominator + , numerator + ) +import GHC.Real (Ratio(..)) +#endif + +#if MIN_VERSION_base(4,4,0) && !(MIN_VERSION_base(4,9,0)) +-- | Extract the numerator of the ratio in reduced form: +-- the numerator and denominator have no common factor and the denominator +-- is positive. +numerator :: Ratio a -> a +numerator (x :% _) = x + +-- | Extract the denominator of the ratio in reduced form: +-- the numerator and denominator have no common factor and the denominator +-- is positive. +denominator :: Ratio a -> a +denominator (_ :% y) = y +#endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base-compat-0.8.2/src/Data/STRef/Compat.hs new/base-compat-0.9.0/src/Data/STRef/Compat.hs --- old/base-compat-0.8.2/src/Data/STRef/Compat.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/base-compat-0.9.0/src/Data/STRef/Compat.hs 2016-01-15 03:45:49.000000000 +0100 @@ -0,0 +1,21 @@ +{-# LANGUAGE CPP, NoImplicitPrelude #-} +module Data.STRef.Compat ( + module Base +, modifySTRef' +) where + +import Data.STRef as Base + +#if !(MIN_VERSION_base(4,6,0)) +import Control.Monad.ST (ST) +import Prelude (seq) + +-- | Strict version of 'modifySTRef' +-- +-- /Since: 4.6.0.0/ +modifySTRef' :: STRef s a -> (a -> a) -> ST s () +modifySTRef' ref f = do + x <- readSTRef ref + let x' = f x + x' `seq` writeSTRef ref x' +#endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base-compat-0.8.2/src/Data/String/Compat.hs new/base-compat-0.9.0/src/Data/String/Compat.hs --- old/base-compat-0.8.2/src/Data/String/Compat.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/base-compat-0.9.0/src/Data/String/Compat.hs 2016-01-15 03:45:49.000000000 +0100 @@ -0,0 +1,15 @@ +{-# LANGUAGE CPP, NoImplicitPrelude #-} +module Data.String.Compat ( + module Base +, String +, lines +, words +, unlines +, unwords +) where + +import Data.String as Base + +#if !(MIN_VERSION_base(4,4,0)) +import Prelude (String, lines, words, unlines, unwords) +#endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base-compat-0.8.2/src/Debug/Trace/Compat.hs new/base-compat-0.9.0/src/Debug/Trace/Compat.hs --- old/base-compat-0.8.2/src/Debug/Trace/Compat.hs 2015-05-13 08:36:37.000000000 +0200 +++ new/base-compat-0.9.0/src/Debug/Trace/Compat.hs 2016-01-15 03:45:49.000000000 +0100 @@ -6,11 +6,21 @@ , traceM , traceShowM ) where + +#if !(MIN_VERSION_base(4,7,0)) || MIN_VERSION_base(4,9,0) import Debug.Trace as Base +#else +import Debug.Trace as Base hiding ( + traceM + , traceShowM + ) +#endif -#if !(MIN_VERSION_base(4,7,0)) +#if !(MIN_VERSION_base(4,9,0)) import Prelude.Compat +#endif +#if !(MIN_VERSION_base(4,7,0)) {-| Like 'trace' but returns the message instead of a third value. @@ -26,11 +36,19 @@ -} traceShowId :: (Show a) => a -> a traceShowId a = trace (show a) a +#endif +#if !(MIN_VERSION_base(4,9,0)) {-| -Like 'trace' but returning unit in an arbitrary monad. Allows for convenient -use in do-notation. Note that the application of 'trace' is not an action in the -monad, as 'traceIO' is in the 'IO' monad. +Like 'trace' but returning unit in an arbitrary 'Applicative' context. Allows +for convenient use in do-notation. + +Note that the application of 'traceM' is not an action in the 'Applicative' +context, as 'traceIO' is in the 'IO' type. While the fresh bindings in the +following example will force the 'traceM' expressions to be reduced every time +the @do@-block is executed, @traceM "not crashed"@ would only be reduced once, +and the message would only be printed once. If your monad is in 'MonadIO', +@liftIO . traceIO@ may be a better option. > ... = do > x <- ... @@ -40,20 +58,20 @@ /Since: 4.7.0.0/ -} -traceM :: (Monad m) => String -> m () -traceM string = trace string $ return () +traceM :: (Applicative f) => String -> f () +traceM string = trace string $ pure () {-| Like 'traceM', but uses 'show' on the argument to convert it to a 'String'. > ... = do > x <- ... -> traceMShow $ x +> traceShowM $ x > y <- ... -> traceMShow $ x + y +> traceShowM $ x + y /Since: 4.7.0.0/ -} -traceShowM :: (Show a, Monad m) => a -> m () +traceShowM :: (Show a, Applicative f) => a -> f () traceShowM = traceM . show #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base-compat-0.8.2/src/Foreign/ForeignPtr/Safe/Compat.hs new/base-compat-0.9.0/src/Foreign/ForeignPtr/Safe/Compat.hs --- old/base-compat-0.8.2/src/Foreign/ForeignPtr/Safe/Compat.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/base-compat-0.9.0/src/Foreign/ForeignPtr/Safe/Compat.hs 2016-01-15 03:45:49.000000000 +0100 @@ -0,0 +1,34 @@ +{-# LANGUAGE CPP, NoImplicitPrelude #-} +module Foreign.ForeignPtr.Safe.Compat ( + -- * Finalised data pointers + ForeignPtr + , FinalizerPtr +#if defined(__HUGS__) || defined(__GLASGOW_HASKELL__) + , FinalizerEnvPtr +#endif + -- ** Basic operations + , newForeignPtr + , newForeignPtr_ + , addForeignPtrFinalizer +#if defined(__HUGS__) || defined(__GLASGOW_HASKELL__) + , newForeignPtrEnv + , addForeignPtrFinalizerEnv +#endif + , withForeignPtr + +#ifdef __GLASGOW_HASKELL__ + , finalizeForeignPtr +#endif + + -- ** Low-level operations + , touchForeignPtr + , castForeignPtr + + -- ** Allocating managed memory + , mallocForeignPtr + , mallocForeignPtrBytes + , mallocForeignPtrArray + , mallocForeignPtrArray0 + ) where + +import Foreign.ForeignPtr diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base-compat-0.8.2/src/Foreign/ForeignPtr/Unsafe/Compat.hs new/base-compat-0.9.0/src/Foreign/ForeignPtr/Unsafe/Compat.hs --- old/base-compat-0.8.2/src/Foreign/ForeignPtr/Unsafe/Compat.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/base-compat-0.9.0/src/Foreign/ForeignPtr/Unsafe/Compat.hs 2016-01-15 03:45:49.000000000 +0100 @@ -0,0 +1,11 @@ +{-# LANGUAGE CPP, NoImplicitPrelude #-} +module Foreign.ForeignPtr.Unsafe.Compat ( + -- ** Unsafe low-level operations + unsafeForeignPtrToPtr +) where + +#if MIN_VERSION_base(4,6,0) +import Foreign.ForeignPtr.Unsafe (unsafeForeignPtrToPtr) +#else +import Foreign.ForeignPtr (unsafeForeignPtrToPtr) +#endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base-compat-0.8.2/src/Foreign/Marshal/Safe/Compat.hs new/base-compat-0.9.0/src/Foreign/Marshal/Safe/Compat.hs --- old/base-compat-0.8.2/src/Foreign/Marshal/Safe/Compat.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/base-compat-0.9.0/src/Foreign/Marshal/Safe/Compat.hs 2016-01-15 03:45:49.000000000 +0100 @@ -0,0 +1,16 @@ +{-# LANGUAGE CPP, NoImplicitPrelude #-} +module Foreign.Marshal.Safe.Compat ( + -- | The module "Foreign.Marshal.Safe" re-exports the other modules in the + -- @Foreign.Marshal@ hierarchy: + module Foreign.Marshal.Alloc + , module Foreign.Marshal.Array + , module Foreign.Marshal.Error + , module Foreign.Marshal.Pool + , module Foreign.Marshal.Utils + ) where + +import Foreign.Marshal.Alloc +import Foreign.Marshal.Array +import Foreign.Marshal.Error +import Foreign.Marshal.Pool +import Foreign.Marshal.Utils diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base-compat-0.8.2/src/Foreign/Marshal/Unsafe/Compat.hs new/base-compat-0.9.0/src/Foreign/Marshal/Unsafe/Compat.hs --- old/base-compat-0.8.2/src/Foreign/Marshal/Unsafe/Compat.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/base-compat-0.9.0/src/Foreign/Marshal/Unsafe/Compat.hs 2016-01-15 03:45:49.000000000 +0100 @@ -0,0 +1,11 @@ +{-# LANGUAGE CPP, NoImplicitPrelude #-} +module Foreign.Marshal.Unsafe.Compat ( + -- * Unsafe functions + unsafeLocalState +) where + +#if MIN_VERSION_base(4,6,0) +import Foreign.Marshal.Unsafe (unsafeLocalState) +#else +import Foreign.Marshal (unsafeLocalState) +#endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base-compat-0.8.2/src/Prelude/Compat.hs new/base-compat-0.9.0/src/Prelude/Compat.hs --- old/base-compat-0.8.2/src/Prelude/Compat.hs 2015-05-13 08:36:37.000000000 +0200 +++ new/base-compat-0.9.0/src/Prelude/Compat.hs 2016-01-15 03:45:49.000000000 +0100 @@ -1,6 +1,6 @@ {-# LANGUAGE CPP, NoImplicitPrelude #-} module Prelude.Compat ( -#if MIN_VERSION_base(4,8,0) +#if MIN_VERSION_base(4,9,0) module Base #else either @@ -101,6 +101,7 @@ , (||) , ($) , error +, errorWithoutStackTrace , undefined , seq @@ -257,7 +258,7 @@ ) where -#if MIN_VERSION_base(4,8,0) +#if MIN_VERSION_base(4,9,0) import Prelude as Base @@ -290,9 +291,21 @@ , sum ) -import Data.Word import Data.Foldable.Compat import Data.Traversable -import Data.Monoid + +# if !(MIN_VERSION_base(4,8,0)) import Control.Applicative +import Data.Monoid +import Data.Word +# endif +#endif + +#if !(MIN_VERSION_base(4,9,0)) +-- | A variant of 'error' that does not produce a stack trace. +-- +-- /Since: 4.9.0.0/ +errorWithoutStackTrace :: [Char] -> a +errorWithoutStackTrace s = error s +{-# NOINLINE errorWithoutStackTrace #-} #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base-compat-0.8.2/src/System/IO/Unsafe/Compat.hs new/base-compat-0.9.0/src/System/IO/Unsafe/Compat.hs --- old/base-compat-0.8.2/src/System/IO/Unsafe/Compat.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/base-compat-0.9.0/src/System/IO/Unsafe/Compat.hs 2016-01-15 03:45:49.000000000 +0100 @@ -0,0 +1,35 @@ +{-# LANGUAGE CPP, NoImplicitPrelude #-} +module System.IO.Unsafe.Compat ( + module Base +, unsafeFixIO +, unsafeDupablePerformIO +) where + +import System.IO.Unsafe as Base + +#if !(MIN_VERSION_base(4,5,0)) +import Control.Exception +import Data.IORef +import GHC.Base +import GHC.IO + +-- | A slightly faster version of `System.IO.fixIO` that may not be +-- safe to use with multiple threads. The unsafety arises when used +-- like this: +-- +-- > unsafeFixIO $ \r -> do +-- > forkIO (print r) +-- > return (...) +-- +-- In this case, the child thread will receive a @NonTermination@ +-- exception instead of waiting for the value of @r@ to be computed. +-- +-- /Since: 4.5.0.0/ +unsafeFixIO :: (a -> IO a) -> IO a +unsafeFixIO k = do + ref <- newIORef (throw NonTermination) + ans <- unsafeDupableInterleaveIO (readIORef ref) + result <- k ans + writeIORef ref result + return result +#endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base-compat-0.8.2/test/Control/Monad/CompatSpec.hs new/base-compat-0.9.0/test/Control/Monad/CompatSpec.hs --- old/base-compat-0.8.2/test/Control/Monad/CompatSpec.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/base-compat-0.9.0/test/Control/Monad/CompatSpec.hs 2016-01-15 03:45:49.000000000 +0100 @@ -0,0 +1,16 @@ +module Control.Monad.CompatSpec (main, spec) where + +import Test.Hspec + +import Control.Monad.Compat +import Prelude () +import Prelude.Compat + +main :: IO () +main = hspec spec + +spec :: Spec +spec = do + describe "(<$!>)" $ do + it "is a strict version of (<$>)" $ do + not <$!> [True, False] `shouldBe` not <$> [True, False] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base-compat-0.8.2/test/Data/Bits/CompatSpec.hs new/base-compat-0.9.0/test/Data/Bits/CompatSpec.hs --- old/base-compat-0.8.2/test/Data/Bits/CompatSpec.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/base-compat-0.9.0/test/Data/Bits/CompatSpec.hs 2016-01-15 03:45:49.000000000 +0100 @@ -0,0 +1,34 @@ +{-# LANGUAGE CPP #-} +module Data.Bits.CompatSpec (main, spec) where + +import Test.Hspec +import Data.Bits.Compat + +main :: IO () +main = hspec spec + +spec :: Spec +spec = do + describe "bitDefault" $ + it "sets the ith bit with all other bits clear" $ do + bitDefault 0 `shouldBe` (1 :: Int) + bitDefault 1 `shouldBe` (2 :: Int) + bitDefault 2 `shouldBe` (4 :: Int) + bitDefault 3 `shouldBe` (8 :: Int) + describe "testBitDefault" $ + it "returns True if the nth bit of the argument is 1" $ do + testBitDefault (10 :: Int) 0 `shouldBe` False + testBitDefault (10 :: Int) 1 `shouldBe` True + testBitDefault (10 :: Int) 2 `shouldBe` False + testBitDefault (10 :: Int) 3 `shouldBe` True + describe "popCountDefault" $ + it "returns the number of set bits in the argument" $ do + popCountDefault (0 :: Int) `shouldBe` 0 + popCountDefault (1 :: Int) `shouldBe` 1 + popCountDefault (10 :: Int) `shouldBe` 2 +#if MIN_VERSION_base(4,7,0) + describe "toIntegralSized" $ + it "converts an Integral type to another as measured by bitSizeMaybe" $ do + toIntegralSized (42 :: Integer) `shouldBe` (Just 42 :: Maybe Int) + toIntegralSized (12345678901234567890 :: Integer) `shouldBe` (Nothing :: Maybe Int) +#endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base-compat-0.8.2/test/Data/Bool/CompatSpec.hs new/base-compat-0.9.0/test/Data/Bool/CompatSpec.hs --- old/base-compat-0.8.2/test/Data/Bool/CompatSpec.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/base-compat-0.9.0/test/Data/Bool/CompatSpec.hs 2016-01-15 03:45:49.000000000 +0100 @@ -0,0 +1,18 @@ +module Data.Bool.CompatSpec (main, spec) where + +import Test.Hspec + +import Data.Bool.Compat + +main :: IO () +main = hspec spec + +spec :: Spec +spec = do + describe "bool" $ do + it "evaluates to first parameter if condition is False" $ do + bool "KO" "OK" False `shouldBe` "KO" + + it "evaluates to second parameter if condition is True" $ do + bool "KO" "OK" True `shouldBe` "OK" + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base-compat-0.8.2/test/Data/Either/CompatSpec.hs new/base-compat-0.9.0/test/Data/Either/CompatSpec.hs --- old/base-compat-0.8.2/test/Data/Either/CompatSpec.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/base-compat-0.9.0/test/Data/Either/CompatSpec.hs 2016-01-15 03:45:49.000000000 +0100 @@ -0,0 +1,25 @@ +module Data.Either.CompatSpec (main, spec) where + +import Test.Hspec + +import Data.Either.Compat + +main :: IO () +main = hspec spec + +spec :: Spec +spec = do + describe "isLeft" $ do + it "returns True for a Left value" $ do + isLeft (Left "23" :: Either String String) `shouldBe` True + + it "returns False for a Right value" $ do + isLeft (Right "23" :: Either String String) `shouldBe` False + + describe "isRight" $ do + it "returns False for a Left value" $ do + isRight (Left "23" :: Either String String) `shouldBe` False + + it "returns True for a Right value" $ do + isRight (Right "23" :: Either String String) `shouldBe` True + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base-compat-0.8.2/test/Data/Function/CompatSpec.hs new/base-compat-0.9.0/test/Data/Function/CompatSpec.hs --- old/base-compat-0.8.2/test/Data/Function/CompatSpec.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/base-compat-0.9.0/test/Data/Function/CompatSpec.hs 2016-01-15 03:45:49.000000000 +0100 @@ -0,0 +1,13 @@ +module Data.Function.CompatSpec (main, spec) where + +import Test.Hspec +import Data.Function.Compat + +main :: IO () +main = hspec spec + +spec :: Spec +spec = do + describe "&" $ do + it "reverses function application" $ do + (False & not) `shouldBe` True diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base-compat-0.8.2/test/Data/Functor/CompatSpec.hs new/base-compat-0.9.0/test/Data/Functor/CompatSpec.hs --- old/base-compat-0.8.2/test/Data/Functor/CompatSpec.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/base-compat-0.9.0/test/Data/Functor/CompatSpec.hs 2016-01-15 03:45:49.000000000 +0100 @@ -0,0 +1,17 @@ +module Data.Functor.CompatSpec (main, spec) where + +import Test.Hspec +import Data.Functor.Compat + +main :: IO () +main = hspec spec + +spec :: Spec +spec = do + describe "void" $ do + it "discards computation result" $ do + void (return 1 :: IO Int) `shouldReturn` () + + describe "$>" $ do + it "is the same as flipped <$" $ do + (Just 5 :: Maybe Int) $> 6 `shouldBe` (Just 6 :: Maybe Int) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base-compat-0.8.2/test/Data/IORef/CompatSpec.hs new/base-compat-0.9.0/test/Data/IORef/CompatSpec.hs --- old/base-compat-0.8.2/test/Data/IORef/CompatSpec.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/base-compat-0.9.0/test/Data/IORef/CompatSpec.hs 2016-01-15 03:45:49.000000000 +0100 @@ -0,0 +1,22 @@ +module Data.IORef.CompatSpec (main, spec) where + +import Test.Hspec + +import Control.Monad +import Data.IORef.Compat + +main :: IO () +main = hspec spec + +spec :: Spec +spec = do + describe "modifyIORef'" $ + it "mutates the contents of an IORef strictly" $ do + ref <- newIORef 0 + replicateM_ 1000000 $ modifyIORef' ref (+1) + readIORef ref `shouldReturn` (1000000 :: Int) + describe "atomicModifyIORef'" $ + it "atomically modifies the contents of an IORef strictly" $ do + ref <- newIORef 0 + replicateM_ 1000000 . atomicModifyIORef' ref $ \n -> (n+1, ()) + readIORef ref `shouldReturn` (1000000 :: Int) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base-compat-0.8.2/test/Data/List/CompatSpec.hs new/base-compat-0.9.0/test/Data/List/CompatSpec.hs --- old/base-compat-0.8.2/test/Data/List/CompatSpec.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/base-compat-0.9.0/test/Data/List/CompatSpec.hs 2016-01-15 03:45:49.000000000 +0100 @@ -0,0 +1,43 @@ +module Data.List.CompatSpec (main, spec) where + +import Test.Hspec +import Data.List.Compat + +data Asymmetric = A | B deriving Show + +instance Eq Asymmetric where + A == _ = True + B == _ = False + +main :: IO () +main = hspec spec + +spec :: Spec +spec = do + describe "dropWhileEnd" $ do + it "drops the largest suffix of a list in which a predicate holds for all elements" $ do + dropWhileEnd (== ' ') "foo " `shouldBe` "foo" + dropWhileEnd (== ' ') "foo bar" `shouldBe` "foo bar" + describe "isSubsequenceOf" $ do + it "returns True if the first list is a subsequence of the second list" $ do + isSubsequenceOf "GHC" "The Glorious Haskell Compiler" `shouldBe` True + isSubsequenceOf "JHC" "The Glorious Haskell Compiler" `shouldBe` False + describe "nub" $ + it "preserves the order of arguments to (==)" $ + nub [A, B] `shouldBe` [A] + describe "nubBy" $ + it "preserves the order of arguments to the equality function" $ + nubBy (<) "12" `shouldBe` "1" + describe "sortOn" $ do + it "sorts a list by comparing the results of a key function applied to each element" $ do + sortOn (>='b') "cba" `shouldBe` "acb" + describe "uncons" $ do + it "decomposes a list into its head and tail" $ do + uncons "" `shouldBe` Nothing + uncons "12" `shouldBe` Just ('1', "2") + describe "union" $ + it "nubs arguments in the same order as (==)" $ do + union [A] [A, B] `shouldBe` [A] + describe "unionBy" $ + it "nubs arguments in the same order as nubBy's equality function" $ do + unionBy (<) "1" "21" `shouldBe` "11" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base-compat-0.8.2/test/Data/Monoid/CompatSpec.hs new/base-compat-0.9.0/test/Data/Monoid/CompatSpec.hs --- old/base-compat-0.8.2/test/Data/Monoid/CompatSpec.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/base-compat-0.9.0/test/Data/Monoid/CompatSpec.hs 2016-01-15 03:45:49.000000000 +0100 @@ -0,0 +1,16 @@ +module Data.Monoid.CompatSpec (main, spec) where + +import Test.Hspec +import Test.QuickCheck + +import Data.Monoid.Compat + +main :: IO () +main = hspec spec + +spec :: Spec +spec = do + describe "<>" $ do + it "is an infix synonym for mappend" $ do + property $ \xs ys -> do + xs <> ys `shouldBe` (mappend xs ys :: String) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base-compat-0.8.2/test/Data/STRef/CompatSpec.hs new/base-compat-0.9.0/test/Data/STRef/CompatSpec.hs --- old/base-compat-0.8.2/test/Data/STRef/CompatSpec.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/base-compat-0.9.0/test/Data/STRef/CompatSpec.hs 2016-01-15 03:45:49.000000000 +0100 @@ -0,0 +1,19 @@ +module Data.STRef.CompatSpec (main, spec) where + +import Test.Hspec + +import Control.Monad +import Control.Monad.ST +import Data.STRef.Compat + +main :: IO () +main = hspec spec + +spec :: Spec +spec = + describe "modifySTRef'" $ + it "should mutate the contents of an STRef strictly" $ + shouldBe (1000000 :: Int) $ runST $ do + ref <- newSTRef 0 + replicateM_ 1000000 $ modifySTRef' ref (+1) + readSTRef ref diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base-compat-0.8.2/test/Data/Version/CompatSpec.hs new/base-compat-0.9.0/test/Data/Version/CompatSpec.hs --- old/base-compat-0.8.2/test/Data/Version/CompatSpec.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/base-compat-0.9.0/test/Data/Version/CompatSpec.hs 2016-01-15 03:45:49.000000000 +0100 @@ -0,0 +1,10 @@ +module Data.Version.CompatSpec (spec) where + +import Test.Hspec +import Data.Version.Compat + +spec :: Spec +spec = do + describe "makeVersion" $ + it "constructs a tagless Version" $ + makeVersion [1,2,3] `shouldBe` Version [1,2,3] [] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base-compat-0.8.2/test/Data/Word/CompatSpec.hs new/base-compat-0.9.0/test/Data/Word/CompatSpec.hs --- old/base-compat-0.8.2/test/Data/Word/CompatSpec.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/base-compat-0.9.0/test/Data/Word/CompatSpec.hs 2016-01-15 03:45:49.000000000 +0100 @@ -0,0 +1,22 @@ +module Data.Word.CompatSpec (main, spec) where + +import Test.Hspec +import Data.Word.Compat + +main :: IO () +main = hspec spec + +spec :: Spec +spec = do + describe "byteSwap16" $ + it "reverses the order of bytes in a Word16 value" $ do + byteSwap16 0x1100 `shouldBe` 0x0011 + byteSwap16 0x1010 `shouldBe` 0x1010 + describe "byteSwap32" $ + it "reverses the order of bytes in a Word32 value" $ do + byteSwap32 0x11001010 `shouldBe` 0x10100011 + byteSwap32 0x10101111 `shouldBe` 0x11111010 + describe "byteSwap64" $ + it "reverses the order of bytes in a Word64 value" $ do + byteSwap64 0x1010111110101111 `shouldBe` 0x1111101011111010 + byteSwap64 0x1100000000000011 `shouldBe` 0x1100000000000011 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base-compat-0.8.2/test/Foreign/Marshal/Alloc/CompatSpec.hs new/base-compat-0.9.0/test/Foreign/Marshal/Alloc/CompatSpec.hs --- old/base-compat-0.8.2/test/Foreign/Marshal/Alloc/CompatSpec.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/base-compat-0.9.0/test/Foreign/Marshal/Alloc/CompatSpec.hs 2016-01-15 03:45:49.000000000 +0100 @@ -0,0 +1,17 @@ +module Foreign.Marshal.Alloc.CompatSpec (main, spec) where + +import Test.Hspec + +import Control.Exception +import Foreign.Marshal.Alloc.Compat +import Foreign.Storable + +main :: IO () +main = hspec spec + +spec :: Spec +spec = do + describe "calloc" $ + it "allocates memory with bytes of value zero" $ do + bracket calloc free $ \ptr -> do + peek ptr `shouldReturn` (0 :: Int) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base-compat-0.8.2/test/Foreign/Marshal/Utils/CompatSpec.hs new/base-compat-0.9.0/test/Foreign/Marshal/Utils/CompatSpec.hs --- old/base-compat-0.8.2/test/Foreign/Marshal/Utils/CompatSpec.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/base-compat-0.9.0/test/Foreign/Marshal/Utils/CompatSpec.hs 2016-01-15 03:45:49.000000000 +0100 @@ -0,0 +1,20 @@ +module Foreign.Marshal.Utils.CompatSpec (main, spec) where + +import Test.Hspec + +import Foreign.Marshal.Alloc +import Foreign.Marshal.Utils.Compat +import Foreign.Ptr +import Foreign.Storable + +main :: IO () +main = hspec spec + +spec :: Spec +spec = do + describe "fillBytes" $ + it "fills a given number of bytes in memory area with a byte value" $ do + alloca $ \ptr -> do + let _ = ptr :: Ptr Int + fillBytes ptr 0 $ sizeOf ptr + peek ptr `shouldReturn` 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base-compat-0.8.2/test/Numeric/CompatSpec.hs new/base-compat-0.9.0/test/Numeric/CompatSpec.hs --- old/base-compat-0.8.2/test/Numeric/CompatSpec.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/base-compat-0.9.0/test/Numeric/CompatSpec.hs 2016-01-15 03:45:49.000000000 +0100 @@ -0,0 +1,24 @@ +module Numeric.CompatSpec (main, spec) where + +import Test.Hspec +import Numeric.Compat + +main :: IO () +main = hspec spec + +spec :: Spec +spec = do + describe "showFFloatAlt" $ do + it "shows a RealFloat value, always using decimal notation" $ + showFFloatAlt Nothing (12 :: Double) "" `shouldBe` "12.0" + it "allows to specify the number of decimal places" $ + showFFloatAlt (Just 4) (12 :: Double) "" `shouldBe` "12.0000" + describe "showGFloatAlt" $ do + it "shows a RealFloat value, using decimal notation if the absolute value lies between 0.1 and 9,999,999" $ + showGFloatAlt Nothing (12 :: Double) "" `shouldBe` "12.0" + it "shows a RealFloat value, using decimal notation and specifying the number of decimal places" $ + showGFloatAlt (Just 4) (12 :: Double) "" `shouldBe` "12.0000" + it "shows a RealFloat value, using scientific notation if the absolute value falls outside of the range" $ + showGFloatAlt Nothing (1234567890 :: Double) "" `shouldBe` "1.23456789e9" + it "shows a RealFloat value, using scientific notation and specifying the number of decimal places" $ + showGFloatAlt (Just 4) (1234567890 :: Double) "" `shouldBe` "1.2346e9" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base-compat-0.8.2/test/System/Environment/CompatSpec.hs new/base-compat-0.9.0/test/System/Environment/CompatSpec.hs --- old/base-compat-0.8.2/test/System/Environment/CompatSpec.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/base-compat-0.9.0/test/System/Environment/CompatSpec.hs 2016-01-15 03:45:49.000000000 +0100 @@ -0,0 +1,120 @@ +{-# LANGUAGE CPP #-} +module System.Environment.CompatSpec (main, spec) where + +import Test.Hspec +import Test.QuickCheck + +import qualified Control.Exception as E +import GHC.IO.Exception (IOErrorType (InvalidArgument)) +import System.Environment.Compat +import System.IO.Error + +main :: IO () +main = hspec spec + +withEnv :: String -> String -> IO a -> IO a +withEnv k v action = E.bracket save restore $ \_ -> do + setEnv k v >> action + where + save = lookupEnv k + restore = maybe (unsetEnv k) (setEnv k) + +withoutEnv :: String -> IO a -> IO a +withoutEnv k action = E.bracket save restore $ \_ -> do + unsetEnv k >> action + where + save = lookupEnv k + restore = maybe (unsetEnv k) (setEnv k) + +spec :: Spec +spec = do + describe "lookupEnv" $ do + it "returns specified environment variable" $ do + withEnv "FOOBAR" "23" $ do + lookupEnv "FOOBAR" `shouldReturn` Just "23" + + it "returns Nothing if specified environment variable is not set" $ do + withoutEnv "FOOBAR" $ do + lookupEnv "FOOBAR" `shouldReturn` Nothing + + describe "unsetEnv" $ do + it "removes specified environment variable" $ do + setEnv "FOO" "foo" + unsetEnv "FOO" + getEnv "FOO" `shouldThrow` isDoesNotExistError + + it "does nothing if specified environment variable is not set" $ do + unsetEnv "BAR" + unsetEnv "BAR" + getEnv "BAR" `shouldThrow` isDoesNotExistError + + it "throws an exception if key is the empty string" $ do + unsetEnv "" `shouldThrow` (== InvalidArgument) . ioeGetErrorType + + it "throws an exception if key contains '='" $ do + unsetEnv "some=key" `shouldThrow` (== InvalidArgument) . ioeGetErrorType + + it "works for arbitrary keys" $ + property $ \k -> ('\NUL' `notElem` k && '=' `notElem` k && (not . null) k) ==> do + setEnv k "foo" + unsetEnv k + getEnv k `shouldThrow` isDoesNotExistError + + describe "setEnv" $ do + it "sets specified environment variable to given value" $ do + unsetEnv "FOO" + setEnv "FOO" "foo" + getEnv "FOO" `shouldReturn` "foo" + + it "resets specified environment variable, if it is already set" $ do + unsetEnv "FOO" + setEnv "FOO" "foo" + setEnv "FOO" "bar" + getEnv "FOO" `shouldReturn` "bar" + + it "removes specified environment variable when value is the empty string" $ do + setEnv "FOO" "foo" + setEnv "FOO" "" + getEnv "FOO" `shouldThrow` isDoesNotExistError + + it "removes specified environment variable when first character of value is NUL" $ do + setEnv "FOO" "foo" + setEnv "FOO" "\NULfoo" + getEnv "FOO" `shouldThrow` isDoesNotExistError + + it "truncates value at NUL character" $ do + unsetEnv "FOO" + setEnv "FOO" "foo\NULbar" + getEnv "FOO" `shouldReturn` "foo" + + it "truncates key at NUL character" $ do + unsetEnv "FOO" + setEnv "FOO\NULBAR" "foo" + getEnv "FOO" `shouldReturn` "foo" + +#if __GLASGOW_HASKELL__ >= 702 + it "works for unicode" $ do + unsetEnv "FOO" + setEnv "FOO" "foo-\955-bar" + getEnv "FOO" `shouldReturn` "foo-\955-bar" +#endif + + it "works for arbitrary values" $ + property $ \v -> ('\NUL' `notElem` v && (not . null) v) ==> do + setEnv "FOO" v + getEnv "FOO" `shouldReturn` v + + it "works for unicode keys" $ do + setEnv "foo-\955-bar" "foo" + getEnv "foo-\955-bar" `shouldReturn` "foo" + + it "throws an exception if key is the empty string" $ do + setEnv "" "foo" `shouldThrow` (== InvalidArgument) . ioeGetErrorType + + it "throws an exception if key contains '='" $ do + setEnv "some=key" "foo" `shouldThrow` (== InvalidArgument) . ioeGetErrorType + + it "works for arbitrary keys" $ + property $ \k -> ('\NUL' `notElem` k && '=' `notElem` k && (not . null) k) ==> do + setEnv k "foo" + getEnv k `shouldReturn` "foo" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base-compat-0.8.2/test/Text/Read/CompatSpec.hs new/base-compat-0.9.0/test/Text/Read/CompatSpec.hs --- old/base-compat-0.8.2/test/Text/Read/CompatSpec.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/base-compat-0.9.0/test/Text/Read/CompatSpec.hs 2016-01-15 03:45:49.000000000 +0100 @@ -0,0 +1,24 @@ +module Text.Read.CompatSpec (main, spec) where + +import Test.Hspec + +import Text.Read.Compat + +main :: IO () +main = hspec spec + +spec :: Spec +spec = do + describe "readMaybe" $ do + it "parses a value" $ do + readMaybe "23" `shouldBe` (Just 23 :: Maybe Int) + + it "returns Nothing if parsing fails" $ do + readMaybe "xx" `shouldBe` (Nothing :: Maybe Int) + + describe "readEither" $ do + it "parses a value" $ do + readEither "23" `shouldBe` (Right 23 :: Either String Int) + + it "returns Left if parsing fails" $ do + readEither "xx" `shouldBe` (Left "Prelude.read: no parse" :: Either String Int)
