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` [![Hackage 
version](https://img.shields.io/hackage/v/base-compat.svg?style=flat)](http://hackage.haskell.org/package/base-compat)
 [![Build 
Status](https://img.shields.io/travis/haskell-compat/base-compat.svg?style=flat)](https://travis-ci.org/haskell-compat/base-compat)
+# A compatibility layer for `base`
+[![Hackage](https://img.shields.io/hackage/v/base-compat.svg)][Hackage: 
base-compat]
+[![Hackage 
Dependencies](https://img.shields.io/hackage-deps/v/base-compat.svg)](http://packdeps.haskellers.com/reverse/base-compat)
+[![Haskell Programming 
Language](https://img.shields.io/badge/language-Haskell-blue.svg)][Haskell.org]
+[![BSD3 
License](http://img.shields.io/badge/license-MIT-brightgreen.svg)][tl;dr Legal: 
MIT]
+[![Build](https://img.shields.io/travis/haskell-compat/base-compat.svg)](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)


Reply via email to