diff --git a/CHANGES.markdown b/CHANGES.markdown
new file mode 100644
--- /dev/null
+++ b/CHANGES.markdown
@@ -0,0 +1,317 @@
+## Changes in 0.15.0 [2026.01.10]
+ - Sync with `base-4.22`/GHC 9.14
+ - Restrict `Data.List.NonEmpty.Compat.unzip` to be of type
+   `NonEmpty (a, b) -> (NonEmpty a, NonEmpty b)`, mirroring similar changes
+   introducted in `base-4.22`.
+
+## Changes in 0.14.1 [2024.12.06]
+ - Sync with `base-4.21`/GHC 9.12
+ - Backport `compareLength` to `Data.List.Compat` and
+   `Data.List.NonEmpty.Compat`
+ - Backport `inits1` and `tails1` to `Data.List.Compat`
+ - Backport `firstA` and `secondA` to `Data.Bitraversable.Compat`
+ - Drop support for pre-8.0 versions of GHC.
+
+## Changes in 0.14.0 [2024.04.30]
+ - Sync with `base-4.20`/GHC 9.10
+ - Backport `foldl'` to `Prelude.Compat`
+ - Backport `List` to `Data.List.Compat` (when building with GHC 9.6 or later)
+ - Backport `append`, `appendList`, `prependList`, `permutations`,
+   `permutations1`, and `sortOn` to `Data.List.NonEmpty.Compat` (when building
+   with GHC 8.0 or later)
+
+## Changes in 0.13.1 [2023.10.11]
+ - Sync with `base-4.19`/GHC 9.8
+ - Backport `unzip` to `Data.Functor.Compat`
+ - Backport `(!?)` and `unsnoc` to `Data.List.Compat`
+ - Backport `getSolo` to `Data.Tuple.Compat` when building against
+   `ghc-prim-0.8.0` (GHC 9.2) or later. To backport `getSolo` to older versions
+   of GHC, import `Data.Tuple.Compat` from `base-compat-batteries` instead.
+ - Backport `decT` and `hdecT` to `Data.Typeable.Compat`
+ - Backport `decTypeRep` to `Type.Reflection.Compat`
+
+## Changes in 0.13.0 [2023.03.10]
+ - Sync with `base-4.18`/GHC 9.6
+ - Backport `liftA2` being re-exported from `Prelude.Compat`.
+ - `Data.Tuple.Compat`'s `Solo` API now matches what is present in `Data.Tuple`
+   in `base-4.18`. In particular, we now re-export both the `MkSolo` and `Solo`
+   data constructors when building with `ghc-prim-0.10.0` or later, with
+   `MkSolo` being preferred over `Solo`. If you want to backport `MkSolo` to
+   earlier versions of GHC, import `Data.Tuple.Compat` from
+   `base-compat-batteries` instead.
+ - Backport `traceWith`, `traceShowWith`, and `traceEventWith` to `Debug.Trace`.
+   Note that `traceEventWith` is only provided when building with `base-4.5` or
+   later, as that is the first version of `base` to provide the `traceEvent`
+   primitive on which `traceEventWith` is defined.
+ - Backport `inits1` and `tails1` to `Data.List.NonEmpty.Compat`.
+ - Backport `minusNaturalMaybe` to `Numeric.Natural.Compat`.
+ - Backport `applyWhen` to `Data.Function.Compat`.
+ - Backport `mapAccumM` and `forAccumM` to `Data.Traversable.Compat`.
+ - Backport `heqT` to `Data.Typeable.Compat`. Note that `heqT` is only defined
+   when building with `base-4.10` or later, as that is the first version of
+   `base` to provide the primitives needed to define `heqT`.
+ - Introduce `Data.Foldable1.Compat` and `Data.Bifoldable1.Compat` modules,
+   which correspond to changes made in `base-4.18.0.0`. You may consider using
+   `base-compat-batteries` instead if you want increase the range of `base`
+   versions that are supported.
+
+## Changes in 0.12.3 [2023.07.12]
+ - This coincides with the `base-compat-batteries-0.12.3` release. Refer to the
+   [`base-compat-batteries` changelog](https://github.com/haskell-compat/base-compat/blob/master/base-compat-batteries/CHANGES.markdown#changes-in-0123-20230712)
+   for more details.
+
+## Changes in 0.12.2 [2022.08.11]
+ - Sync with `base-4.17`/GHC 9.4
+ - Backport `(.^.)`, `(.>>.)`, `(.<<.)`, `(!>>.)`, `(!<<.)`, `oneBits` to
+   `Data.Bits.Compat`
+ - Backport `pattern TypeRep` to `Type.Reflection.Compat`
+
+## Changes in 0.12.1 [2021.10.30]
+ - Backport `Solo` to `Data.Tuple.Compat` when building with `ghc-prim-0.7.0`
+   or later
+
+## Changes in 0.12.0 [2021.08.29]
+ - Sync with `base-4.16`/GHC 9.2
+ - `Data.Semigroup.Compat{.Repl}` no longer re-exports the `Option` data type
+   or the `option` function, as both have been removed in `base-4.16`.
+ - Backport `readBin` and `showBin` to `Numeric.Compat`
+ - Backport `readBinP` to `Text.Read.Lex.Compat`
+
+## Changes in 0.11.2 [2020.09.30]
+ - Sync with `base-4.15`/GHC 9.0
+ - Backport `singleton` to `Data.List.Compat` and `Data.List.NonEmpty.Compat`
+ - Backport `hGetContents'`, `getContents'`, and `readFile'` added to
+   `System.IO.Compat`
+
+## Changes in 0.11.1 [2020.01.27]
+ - Sync with `base-4.14`/GHC 8.10
+ - Backport `isResourceVanishedError`, `resourceVanishedErrorType`, and
+   `isResourceVanishedErrorType` to `System.IO.Error.Compat`.
+
+## Changes in 0.11.0 [2019.09.06]
+ - Sync with `base-4.13`/GHC 8.8
+ - Backport `MonadFail(fail)` to `Prelude.Compat` and `Control.Monad.Compat`.
+
+   Because `Prelude.Compat.fail` now corresponds to the `fail` from `MonadFail`
+   instead of `Monad`, some care is required to implement `Monad.fail` on
+   pre-8.8 versions of GHC. The following template is recommended:
+
+   ```haskell
+   import Prelude.Compat
+   import qualified Control.Monad      as Monad
+   import qualified Control.Monad.Fail as Fail
+
+   data Blah a = ...
+
+   instance Functor Blah where ...
+   instance Applicative Blah where ...
+
+   instance Monad.Monad Blah where
+     (>>=) = ...
+   #if !(MIN_VERSION_base(4,13,0))
+     fail = Fail.fail
+   #endif
+
+   instance Fail.MonadFail Blah where
+     fail = ...
+   ```
+
+   This approach is also backwards-compatible with previous releases of
+   `base-compat`.
+
+   Note that the `MonadFail` class has only been in `base` since
+   `base-4.9`/GHC 8.0, so accordingly, this can only be backported back
+   to GHC 8.0. If you wish to have a version of
+   `Prelude.Compat`/`Control.Monad.Compat` that backports
+   `MonadFail` to older GHCs (by conditionally depending on the `fail`
+   library), use the `Prelude.Compat`/`Control.Monad.Compat` modules from the
+   `base-compat-batteries` package.
+
+ - Introduce the `Data.Type.Equality.Compat` module, which re-exports
+   `Data.Type.Equality` if using `base-4.7`/GHC-7.8 or later. If using an older
+   version of `base`, this module is empty.
+
+   If you wish to have a version of
+   `Data.Type.Equality.Compat` with older GHCs
+   (by conditionally depending on the `type-equality` library),
+   use the `Data.Type.Equality.Compat` module from the
+   `base-compat-batteries` package.
+
+## Changes in 0.10.5 [2018.10.18]
+ - Enable `BangPatterns` in `Prelude.Compat`.
+
+## Changes in 0.10.4 [2018.07.03]
+ - Make more modules `Trustworthy`. In particular, fix a regression in which
+   `Prelude.Compat` was inferred as `Unsafe` by explicitly marking it as
+   `Trustwothy`.
+
+## Changes in 0.10.3 [2018.07.02]
+ - Backport the proper fixity for `($!)`, which was accidentally omitted in
+   `base-compat-0.10.2`.
+
+## Changes in 0.10.2 [2018.07.02]
+ - Sync with `base-4.12`/GHC 8.6
+ - Backport `RuntimeRep`-polymorphic versions of `($!)` and `throw` to
+   `Prelude.Compat` and `Control.Exception.Compat`, respectively
+   (if using `base-4.10`/GHC 8.2 or later).
+ - Introduce the `Data.Functor.Contravariant.Compat` module, which reexports
+   `Data.Functor.Contravariant` if using `base-4.12`/GHC 8.6 or later.
+
+   See `Data.Functor.Contravariant.Compat` in the corresponding
+   `base-compat-batteries` release for a version with a wider support window.
+
+## Changes in 0.10.1 [2018.04.10]
+ - Add `Data.List.NonEmpty.Compat`.
+ - Reexport `(Data.Semigroup.<>)` from `Data.Monoid.Compat` back to `base-4.9`.
+
+## Changes in 0.10.0 [2018.04.05]
+ - Sync with `base-4.11`/GHC 8.4
+ - Backport `Semigroup((<>))` to `Prelude.Compat`.
+
+   Note that the `Semigroup` class has only been in `base` since
+   `base-4.9`/GHC 8.0, so accordingly, this can only be backported back
+   to GHC 8.0. If you wish to have a version of `Prelude.Compat` that backports
+   `Semigroup` to older GHCs (by conditionally depending on the `semigroups`
+   library), use the `Prelude.Compat` module from the `base-compat-batteries`
+   package.
+ - Backport `(<&>)` to `Data.Functor.Compat`
+ - Backport `iterate'` to `Data.List.Compat`
+ - Backport `showHFloat` to `Numeric.Compat`
+ - Backport a `RuntimeRep`-polymorphic `withTypeable` function to
+   `Type.Reflection.Compat`. (This is only exported on `base-4.10`/GHC 8.2.)
+ - Introduce the following modules, back until the oldest version of `base`
+   that can support backporting them. If you wish to use them in conjunction
+   with older versions of `base`, use the `base-compat-batteries` package.
+   - `Control.Monad.Fail.Compat` (back until `base-4.9`/GHC 8.0)
+   - `Control.Monad.IO.Class.Compat` (back until `base-4.9`/GHC 8.0)
+   - `Data.Bifunctor` (back until `base-4.8`/GHC 7.10)
+   - `Data.Bifoldable` and `Data.Bitraversable` (back until `base-4.10`/GHC 8.2)
+   - `Data.Functor.Compose.Compat`, `Data.Functor.Product.Compat`, and
+     `Data.Functor.Sum.Compat` (back until `base-4.9`/GHC 8.0)
+   - `Data.Functor.Identity.Compat` (back until `base-4.8`/GHC 7.10)
+   - `Data.Semigroup.Compat` (back until `base-4.9`/GHC 8.0)
+   - `Data.Void.Compat` (back until `base-4.8`/GHC 7.10)
+   - `Numeric.Natural.Compat` (back until `base-4.8`/GHC 7.10)
+ - Introduce versions of modules with the suffix `.Repl`. These simply reexport
+   the contents of their counterparts without the `.Repl` suffix to provide
+   a globally unique namespace to import from in the event one wants to import
+   `base-compat` modules into GHCi. (In `base-compat-batteries`, the
+   corresponding suffix is `.Repl.Batteries`.)
+
+## Changes in 0.9.3 [2017.04.10]
+ - Sync with `base-4.10`/GHC 8.2
+ - Backport `fromLeft`/`fromRight` to `Data.Either.Compat`
+ - Backport implementations of `maximumBy`/`minimumBy` which use constant stack
+   space to `Data.Foldable.Compat`
+ - Backport `asProxyTypeOf` with a generalized type signature to
+   `Data.Proxy.Compat`
+ - Backport `gcoerceWith` to `Data.Type.Coercion.Compat`
+ - Backport `plusForeignPtr` to `Foreign.ForeignPtr.Compat`
+
+## Changes in 0.9.2
+ - Allow building on the HaLVM
+
+## Changes in 0.9.1
+ - Use the more efficient version of `replicateM` and `replicateM_` introduced
+   in `base-4.9`
+
+## Changes in 0.9.0
+ - Sync with `base-4.9`/GHC 8.0
+ - Weakened `RealFloat` constraints on `realPart`, `imagPart`, `conjugate`,
+   `mkPolar`, and `cis` in `Data.Complex.Compat`
+ - Backport `Foreign.ForeignPtr.Safe` and `Foreign.Marshal.Safe`
+ - Generalize `filterM`, `forever`, `mapAndUnzipM`, `zipWithM`, `zipWithM_`,
+   `replicateM`, and `replicateM_` in `Control.Monad` from `Monad` to
+   `Applicative`
+ - Backport `.Unsafe.Compat` modules (for `Control.Monad.ST`,
+   `Control.Monad.ST.Lazy`, `Foreign.ForeignPtr`, and `Foreign.Marshal`)
+ - Backport `forkFinally` and `forkOSWithUnmask` to `Control.Concurrent.Compat`
+ - Backport `Data.Functor.Const`
+ - Backport `modifyIORef'`, `atomicModifyIORef'` and `atomicWriteIORef` to
+   `Data.IORef.Compat`
+ - `Data.Ratio.{denominator,numerator}` have no `Integral` constraint anymore
+ - Backport `modifySTRef'` to `Data.STRef.Compat`
+ - Export `String`, `lines`, `words`, `unlines`, and `unwords` to
+   `Data.String.Compat`
+ - Generalize `Debug.Trace.{traceM, traceShowM}` from `Monad` to `Applicative`
+ - Backport `errorWithoutStackTrace` to `Prelude.Compat`
+ - Backport `unsafeFixIO` and `unsafeDupablePerformIO` to
+   `System.IO.Unsafe.Compat`
+
+## Changes in 0.8.2
+ - Backport `bitDefault`, `testBitDefault`, and `popCountDefault` in
+   `Data.Bits.Compat` to all versions of `base`
+   - Backport `toIntegralSized` to `base-4.7`
+ - Backport `nub` and `nubBy` (as well as `union` and `unionBy`, which are
+   implemented in terms of them) to fix logic error in `Data.List.Compat`
+ - Backport `byteSwap16`, `byteSwap32`, and `byteSwap64` to `Data.Word.Compat`
+ - Backport `fillBytes` in `Foreign.Marshal.Utils.Compat`
+ - Backport `showFFloatAlt` and `showGFloatAlt` to `Numeric.Compat`
+
+## Changes in 0.8.1.1
+ - Fixed Windows build
+
+## Changes in 0.8.1
+ - Implement `setEnv` and `unsetEnv` in `System.Environment.Compat` (which were
+   ported from the `setenv` package). As a result, `base-compat` now depends
+   on `unix` on POSIX-like operating systems.
+ - Drop GHC 6.12 (and `base-4.2.0.0`) compatibility
+
+## Changes in 0.8.0.1
+ - Retrospective version bump updating the changelog to reflect the changes
+   made in 0.8.0
+
+## Changes 0.8.0
+ - All orphan instances were split off into a separate package,
+   [`base-orphans`](https://github.com/haskell-compat/base-orphans)
+ - `base-compat` no longer redefines the data types `Down` and `Alt`. See
+   [here](https://github.com/haskell-compat/base-compat/issues/17) for
+   the discussion that led to this change.
+ - Update `Control.Monad.Compat` for `base-4.8.0.0`
+ - Update `Data.List.Compat` for `base-4.8.0.0`
+ - Update `Data.Foldable.Compat` for `base-4.8.0.0`
+
+## Changes in 0.7.1
+ - Backported `Alt` to `Data.Monoid.Compat`
+ - Backported `Down` to `Data.Ord.Compat`
+
+## Changes in 0.7.0
+ - Add functions and orphan instances introduced by changes to
+   `base-4.7.0.0` and `base-4.8.0.0`
+
+## Changes in 0.6.0
+ - Update `Prelude.Compat` for `base-4.8.0.0` and AMP
+
+## Changes in 0.5.0
+ - Remove Control.Exception.Base.Compat and GHC.Exception.Compat
+ - Add System.Exit.Compat.die
+ - Compatibility with base-4.7.1
+
+## Changes in 0.4.1
+ - Add `setEnv` and `unsetEnv` to `System.Environment.Compat`
+
+## Changes in 0.4.0
+ - Major refactoring: base-compat no longer aims to replace all base,
+   only new code is included in module .Compat
+ - Removed stubbed modules
+ - Removed generation scripts
+
+## Changes in 0.3
+ - Added functions from Base 4.7 (bool, isLeft, isRight)
+ - Added instances from Base 4.7 (Either Foldable, Traversable,...)
+
+## Changes in 0.2.1
+ - Fix build on windows
+
+## Changes in 0.2.0
+ - Re-export everything from base
+ - provides access to `VERSION_base` and `MIN_VERSION_base` CPP macros (with
+   `#include "base-compat.h"`)
+ - Do not re-export `System.IO.Error.catch` from `Prelude` for `base` < 4.6.0
+ - Add `Eq`/`Ord` instance for `ErrorCall`
+ - Remove `GHC.IOBase`, `GHC.Handle`, `Control.Concurrent.QSem`,
+   `Control.Concurrent.QSemN`, `Control.Concurrent.SampleVar`, `Data.HashTable`
+
+## Changes in 0.1.0
+ - Remove getExecutablePath, it did not work with GHC < 7.2 (patches welcome!)
+ - Add `<>`
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2012 Simon Hengel <sol@typeful.net>
+Copyright (c) 2012-2018 Simon Hengel <sol@typeful.net> and Ryan Scott <ryan.gl.scott@gmail.com>
 
 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 --git a/README.markdown b/README.markdown
new file mode 100644
--- /dev/null
+++ b/README.markdown
@@ -0,0 +1,337 @@
+# 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]
+
+[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
+of base to a wider (older) range of compilers.
+
+In addition, successful library proposals that have been accepted to be part of
+upcoming versions of `base` are also included.  This package is not intended to
+replace `base`, but to complement it.
+
+Note that `base-compat` does not add any orphan instances.  There is a separate
+package [`base-orphans`](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.
+
+`base-compat` is intentionally designed to have zero dependencies. As a
+consequence, there are some modules that can only be backported up to certain
+versions of `base`. If an even wider support window is desired in these
+scenarios, there also exists a `base-compat-batteries` package which augments
+`base-compat` with certain compatibility package dependencies. For more info,
+see the [Dependencies](#dependencies) section.
+
+## Basic usage
+
+In your cabal file, you should have something like this:
+
+```
+  build-depends:      base              >= 4.3
+                    , base-compat       >= 0.9.0
+```
+
+Then, lets say you want to use the `isRight` function introduced with
+`base-4.7.0.0`.  Replace:
+
+```
+import Data.Either
+```
+
+with
+
+```
+import Data.Either.Compat
+```
+
+_Note (1)_: There is no need to import both unqualified.  The `.Compat` modules
+re-exports the original module.
+
+_Note (2)_: If a given module `.Compat` version is not defined, that either
+means that:
+
+* The module has not changed in recent base versions, thus no `.Compat` is
+  needed.
+* The module has changed, but the changes depend on newer versions of GHC, and
+  thus are not portable.
+* The module has changed, but those changes have not yet been merged in
+  `base-compat`: patches are welcomed!
+
+## Using `Prelude.Compat`
+
+If you want to use `Prelude.Compat` (which provides all the
+AMP/Traversable/Foldable changes from `base-4.8.0.0`), it's best to hide
+`Prelude`, e.g.:
+
+    import Prelude ()
+    import Prelude.Compat
+
+    main :: IO ()
+    main = mapM_ print (Just 23)
+
+Alternatively, you can use the `NoImplicitPrelude` language extension:
+
+    {-# LANGUAGE NoImplicitPrelude #-}
+    import Prelude.Compat
+
+    main :: IO ()
+    main = mapM_ print (Just 23)
+
+Note that we use
+
+    mapM_ :: (Foldable t, Monad m) => (a -> m b) -> t a -> m ()
+
+from `Data.Foldable` here, which is only exposed from `Prelude` since
+`base-4.8.0.0`.
+
+Using this approach allows you to write code that works seamlessly with all
+versions of GHC that are supported by `base-compat`.
+
+## What is covered
+So far the following is covered.
+
+### For compatibility with the latest released version of `base`
+
+ * `Prelude.Compat` incorporates the AMP/Foldable/Traversable changes and
+   exposes the same interface as `Prelude` from `base-4.9.0.0`
+ * `System.IO.Error.catch` is not re-exported from `Prelude.Compat` for older
+   versions of `base`
+ * `Text.Read.Compat.readMaybe`
+ * `Text.Read.Compat.readEither`
+ * `Data.Monoid.Compat.<>`
+ * Added `bitDefault`, `testBitDefault`, `popCountDefault`, `(.^.)`, `(.>>.)`,
+   `(.<<.)`, `(!>>.)`, and `(!<<.)` to `Data.Bits.Compat`
+ * Added `toIntegralSized` and `oneBits` to `Data.Bits.Compat` (if using `base-4.7` or later)
+ * Added `firstA` and `secondA` to `Data.Bitraversable.Compat`
+ * Added `bool` function to `Data.Bool.Compat`
+ * Added `isLeft`, `isRight`, `fromLeft`, and `fromRight` to `Data.Either.Compat`
+ * Added `forkFinally` to `Control.Concurrent.Compat`
+ * Added `withMVarMasked` function to `Control.Concurrent.MVar.Compat`
+ * Added `(<$!>)` function to `Control.Monad.Compat`
+ * Weakened `RealFloat` constraints on `realPart`, `imagPart`, `conjugate`, `mkPolar`,
+   and `cis` in `Data.Complex.Compat`
+ * Added more efficient `maximumBy`/`minimumBy` to `Data.Foldable.Compat`
+ * Added `($>)` and `void` functions to `Data.Functor.Compat`
+ * `(&)` and `applyWhen` functions 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`
+ * `inits1` and `tails1` to `Data.List.Compat`
+ * `compareLength` to `Data.List.Compat` and `Data.List.NonEmpty.Compat`
+ * `asProxyTypeOf` with a generalized type signature to `Data.Proxy.Compat`
+ * `modifySTRef'` to `Data.STRef.Compat`
+ * `String`, `lines`, `words`, `unlines`, and `unwords` to `Data.String.Compat`
+ * `gcoerceWith` to `Data.Type.Coercion.Compat`
+ * `makeVersion` function to `Data.Version.Compat`
+ * `traceId`, `traceShowId`, `traceM`, `traceShowM`, `traceWith`,
+   `traceShowWith`, and `traceEventWith` functions to `Debug.Trace.Compat`
+ * `byteSwap16`, `byteSwap32`, and `byteSwap64` to `Data.Word.Compat`
+ * `plusForeignPtr` to `Foreign.ForeignPtr.Compat`
+ * `calloc` and `callocBytes` functions to `Foreign.Marshal.Alloc.Compat`
+ * `callocArray` and `callocArray0` functions to `Foreign.Marshal.Array.Compat`
+ * `fillBytes` to `Foreign.Marshal.Utils.Compat`
+ * Added `Data.List.Compat.scanl'`
+ * `showFFloatAlt`, `showGFloatAlt`, `readBin`, and `showBin` to `Numeric.Compat`
+ * `lookupEnv`, `setEnv` and `unsetEnv` to `System.Environment.Compat`
+ * `unsafeFixIO` and `unsafeDupablePerformIO` to `System.IO.Unsafe.IO`
+ * `RuntimeRep`-polymorphic `($!)` to `Prelude.Compat`
+ * `liftA2` is re-exported from `Prelude.Compat`
+ * `foldl'` is re-exported from `Prelude.Compat`
+ * `RuntimeRep`-polymorphic `throw` to `Control.Exception.Compat`
+ * `isResourceVanishedError`, `resourceVanishedErrorType`, and
+   `isResourceVanishedErrorType` to `System.IO.Error.Compat`
+ * `singleton` to `Data.List.Compat` and `Data.List.NonEmpty.Compat`
+ * `inits1` and `tails1` to `Data.List.NonEmpty.Compat`
+ * `permutations`, `permutations1`, and `sortOn` to `Data.List.NonEmpty.Compat`
+ * `Data.List.NonEmpty.Compat`'s `unzip` function is restricted to only work over `NonEmpty` lists
+ * `hGetContents'`, `getContents'`, and `readFile'` to `System.IO.Compat`
+ * `readBinP` to `Text.Read.Lex.Compat`
+ * `withTypeable` and `pattern TypeRep` to `Type.Reflection.Compat`
+ * `minusNaturalMaybe` to `Numeric.Natural.Compat`
+ * `mapAccumM` and `forAccumM` to `Data.Traversable.Compat`
+ * `heqT` to `Data.Typeable.Compat`
+ * `unzip` to `Data.Functor.Compat`
+ * `(!?)` and `unsnoc` to `Data.List.Compat`
+ * `List` to `Data.List.Compat` (when building with GHC 9.6 or later)
+ * `getSolo` to `Data.Tuple.Compat`
+ * `decT` and `hdecT` to `Data.Typeable.Compat`
+ * `decTypeRep` to `Type.Reflection.Compat`
+
+## 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
+```
+
+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   -- ^ @since 4.8.0.0
+    countTrailingZeros :: b -> Int  -- ^ @since 4.8.0.0
+```
+
+This raises the question: how can `FiniteBits` be backported consistently
+across all versions of `base`? One approach is to backport the API exposed in
+`base-4.8.0.0` on versions prior to `4.7.0.0`.  The problem with this is that
+`countLeadingZeros` and `countTrailingZeros` are not exposed in `base-4.7.0.0`,
+so instances of `FiniteBits` would have to be declared like this:
+
+```haskell
+instance FiniteBits Foo where
+    finiteBitSize = ...
+#if MIN_VERSION_base(4,8,0) || !(MIN_VERSION_base(4,7,0))
+    countLeadingZeros = ...
+    countTrailingZeros = ...
+#endif
+```
+
+Another approach is to backport the API from `base-4.7.0.0` and to declare
+additional methods outside of the class:
+
+```haskell
+#if MIN_VERSION_base(4,7,0) && !(MIN_VERSION_base(4,8,0))
+countLeadingZeros :: FiniteBits b => b -> Int
+countLeadingZeros = {- default implementation #-}
+#endif
+```
+
+The situation is only slightly better for classes which exist across all versions of `base`,
+but have grown their API. For example, it's tempting to define
+
+```haskell
+#if !(MIN_VERSION_base(4,8,0))
+displayException :: Exception e => e -> String
+displayException = show
+#endif
+```
+
+As with the previous approach, you won't be able to define new members of the type
+class without CPP guards. In other words, the non-CPP approach would limit
+uses to the lowest common denominator.
+
+As neither approach is a very satisfactory solution, and to embrace
+consistency, we do not pursue either approach. For similar reasons, we do not
+backport data types.
+
+### Dependencies
+
+`base-compat` is designed to have zero dependencies (besides libraries that
+ship with GHC itself). A consequence of this choice is that there are certain
+modules that have a "limited" support window. An important example of this is
+`Prelude.Compat`, which backports the `Semigroup` class to versions of `base`
+older than 4.11 (when it was added to the `Prelude`). Because `Semigroup` was
+not added to `base` until `base-4.9`, `base-compat` cannot backport it to
+any earlier version of `base` than this.
+
+If you would instead desire to be able to use a version of `Prelude.Compat`
+that _does_ backport `Semigroup` to even older versions of `base`, even if it
+means pulling in other dependencies, then you are in luck. There also exists
+a `base-compat-batteries` package, which exposes a strict superset of the API
+in `base-compat`. `base-compat-batteries` has all the same modules as
+`base-compat`, but exposes more functionality on more versions of `base` by
+reexporting things from compatibility libraries whenever necessary. (For
+instance, `base-compat-batteries` exports the `Semigroup` class from the
+`semigroups` library when built against versions of `base` older than 4.9.)
+
+Because `base-compat` and `base-compat-batteries` have the same module names,
+they are quite easy to switch out for one another in library projects, at the
+expense of having clashing names if one tries to import them in GHCi. To
+work around this issue, `base-compat` and `base-compat-batteries` also provide
+copies of each module with the suffix `.Repl` (for `base-compat`) and
+`.Repl.Batteries` (for `base-compat-batteries`) to give them globally unique
+namespaces in the event one wants to import them into GHCi.
+
+Here is a list of compatibility libraries that `base-compat-batteries` depends
+on, paired with the things that each library backports:
+
+* [`bifunctor-classes-compat`](http://hackage.haskell.org/package/bifunctor-classes-compat)
+  for the
+  [`Bifoldable`](http://hackage.haskell.org/package/base-4.10.0.0/docs/Data-Bifoldable.html#t:Bifoldable)
+  and
+  [`Bitraversable`](http://hackage.haskell.org/package/base-4.10.0.0/docs/Data-Bitraversable.html#t:Bitraversable)
+  type classes, introduced in `base-4.10.0.0`
+* [`contravariant`](http://hackage.haskell.org/package/contravariant)
+  for the [`Contravariant`](http://hackage.haskell.org/package/base-4.12.0.0/docs/Data-Functor-Contravariant.html#t:Contravariant)
+  type class, introduced in `base-4.12.0.0`.
+* [`foldable1-classes-compat`](https://hackage.haskell.org/package/foldable1-classes-compat)
+  for the [`Foldable1`](https://hackage.haskell.org/package/foldable1-classes-compat-0.1/docs/Data-Foldable1.html#t:Foldable1)
+  and [`Bifoldable1`](https://hackage.haskell.org/package/foldable1-classes-compat-0.1/docs/Data-Bifoldable1.html#t:Bifoldable1)
+  type classes, introduced in `base-4.18.0.0`
+* [`OneTuple`](http://hackage.haskell.org/package/OneTuple)
+  for the [`Solo`](https://hackage.haskell.org/package/base-4.16.0.0/docs/Data-Tuple.html#t:Solo)
+  data type, introduced in `ghc-prim-0.7.0`
+
+## Version policy
+
+This package follows the [Haskell Package Versioning
+Policy](https://pvp.haskell.org/). As such, if a new `base-compat` release only
+adds new exports, then as a general rule, we will release it with a minor
+version bump. Moreover, since `base-compat` does not backport data type or
+class definitions (see the "What is not covered" section above), `base-compat`
+usually has fewer major version bumps than `base` itself.
+
+An exception to the general rule about adding new exports is the
+`Prelude.Compat` module. If a new `base-compat` release adds any new exports,
+then it will _always_ be accompanied by a major version bump, even if there are
+no other API changes. This is because of the special nature of
+`Prelude.Compat`, which is designed to be imported unqualified. Pre-emptively
+bumping the major version number is meant to signal to downstream libraries
+that they should check to see if the new `Prelude.Compat` additions will clash
+with identifiers of the same names in their code.
+
+## Supported versions of GHC/`base`
+
+ * `ghc-9.14.*` / `base-4.22.*`
+ * `ghc-9.12.*` / `base-4.21.*`
+ * `ghc-9.10.*` / `base-4.20.*`
+ * `ghc-9.8.*`  / `base-4.19.*`
+ * `ghc-9.6.*`  / `base-4.18.*`
+ * `ghc-9.4.*`  / `base-4.17.*`
+ * `ghc-9.2.*`  / `base-4.16.*`
+ * `ghc-9.0.*`  / `base-4.15.*`
+ * `ghc-8.10.*` / `base-4.14.*`
+ * `ghc-8.8.*`  / `base-4.13.*`
+ * `ghc-8.6.*`  / `base-4.12.*`
+ * `ghc-8.4.*`  / `base-4.11.*`
+ * `ghc-8.2.*`  / `base-4.10.*`
+ * `ghc-8.0.*`  / `base-4.9.*`
+
+We also make an attempt to keep `base-compat` building with GHC HEAD, but due
+to its volatility, it may not work at any given point in time. If it doesn't,
+please report it!
+
+Patches are welcome; add tests for new code!
diff --git a/base-compat.cabal b/base-compat.cabal
--- a/base-compat.cabal
+++ b/base-compat.cabal
@@ -1,64 +1,212 @@
 name:             base-compat
-version:          0.5.0
+version:          0.15.0
 license:          MIT
 license-file:     LICENSE
-copyright:        (c) 2012-2014 Simon Hengel,
-                  (c) 2014 João Cristóvão
-author:           Simon Hengel <sol@typeful.net>, João Cristóvão <jmacristovao@gmail.com>
-maintainer:       Simon Hengel <sol@typeful.net>, João Cristóvão <jmacristovao@gmail.com>
+copyright:        (c) 2012-2018 Simon Hengel,
+                  (c) 2014-2018 João Cristóvão,
+                  (c) 2015-2018 Ryan Scott
+author:           Simon Hengel <sol@typeful.net>,
+                  João Cristóvão <jmacristovao@gmail.com>,
+                  Ryan Scott <ryan.gl.scott@gmail.com>
+maintainer:       Simon Hengel <sol@typeful.net>,
+                  João Cristóvão <jmacristovao@gmail.com>,
+                  Ryan Scott <ryan.gl.scott@gmail.com>
 build-type:       Simple
-cabal-version:    >= 1.8
-category:         System
+cabal-version:    >= 1.10
+category:         Compatibility
 synopsis:         A compatibility layer for base
-description:      Ban CPP from your code.  See the README for what is covered:
-                  <https://github.com/sol/base-compat#readme>
+description:      Provides functions available in later versions of @base@ to
+                  a wider range of compilers, without requiring you to use CPP
+                  pragmas in your code.  See the
+                  <https://github.com/haskell-compat/base-compat/blob/master/base-compat/README.markdown README>
+                  for what is covered. Also see the
+                  <https://github.com/haskell-compat/base-compat/blob/master/base-compat/CHANGES.markdown changelog>
+                  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>@,
+                  for that.
+                  .
+                  In addition, @base-compat@ does not backport any data types
+                  or type classes. See
+                  @<https://github.com/haskell-compat/base-compat/blob/master/base-compat/README.markdown#data-types-and-type-classes this section of the README>@
+                  for more info.
+                  .
+                  @base-compat@ is designed to have zero dependencies. For a
+                  version of @base-compat@ that depends on compatibility
+                  libraries for a wider support window, see the
+                  @<http://hackage.haskell.org/package/base-compat-batteries base-compat-batteries>@
+                  package. Most of the modules in this library have the same
+                  names as in @base-compat-batteries@ to make it easier to
+                  switch between the two. There also exist versions of each
+                  module with the suffix @.Repl@, which are distinct from
+                  anything in @base-compat-batteries@, to allow for easier
+                  use in GHCi.
+extra-source-files: CHANGES.markdown, README.markdown
+tested-with:        GHC == 8.0.2
+                  , GHC == 8.2.2
+                  , GHC == 8.4.4
+                  , GHC == 8.6.5
+                  , GHC == 8.8.4
+                  , GHC == 8.10.7
+                  , GHC == 9.0.2
+                  , GHC == 9.2.8
+                  , GHC == 9.4.8
+                  , GHC == 9.6.7
+                  , GHC == 9.8.4
+                  , GHC == 9.10.3
+                  , GHC == 9.12.2
+                  , GHC == 9.14.1
 
 source-repository head
   type: git
-  location: https://github.com/sol/base-compat
+  location: https://github.com/haskell-compat/base-compat
+  subdir: base-compat
 
 library
   ghc-options:
       -Wall
+  default-language:
+      Haskell2010
   build-depends:
-      base == 4.*
-    , errorcall-eq-instance
-    , setenv
-  extensions:
-      CPP
-    , NoImplicitPrelude
+      base >= 4.9 && < 5,
+      ghc-prim
   ghc-options:
-    -fno-warn-duplicate-exports
+      -Wno-duplicate-exports -Wno-trustworthy-safe
 
   hs-source-dirs:
       src
 
   exposed-modules:
-      Prelude.Compat
-      Control.Applicative.Compat
+      Control.Concurrent.Compat
+      Control.Concurrent.MVar.Compat
       Control.Exception.Compat
       Control.Monad.Compat
+      Control.Monad.Fail.Compat
+      Control.Monad.IO.Class.Compat
+      Control.Monad.ST.Lazy.Unsafe.Compat
+      Control.Monad.ST.Unsafe.Compat
+      Data.Bifoldable.Compat
+      Data.Bifoldable1.Compat
+      Data.Bifunctor.Compat
+      Data.Bitraversable.Compat
+      Data.Bits.Compat
       Data.Bool.Compat
+      Data.Complex.Compat
       Data.Either.Compat
       Data.Foldable.Compat
+      Data.Foldable1.Compat
+      Data.Function.Compat
       Data.Functor.Compat
+      Data.Functor.Compose.Compat
+      Data.Functor.Const.Compat
+      Data.Functor.Contravariant.Compat
+      Data.Functor.Identity.Compat
+      Data.Functor.Product.Compat
+      Data.Functor.Sum.Compat
+      Data.IORef.Compat
+      Data.List.Compat
+      Data.List.NonEmpty.Compat
       Data.Monoid.Compat
+      Data.Proxy.Compat
+      Data.Ratio.Compat
+      Data.Semigroup.Compat
+      Data.STRef.Compat
+      Data.String.Compat
       Data.Traversable.Compat
+      Data.Tuple.Compat
+      Data.Typeable.Compat
+      Data.Type.Coercion.Compat
+      Data.Type.Equality.Compat
+      Data.Version.Compat
+      Data.Void.Compat
+      Data.Word.Compat
+      Debug.Trace.Compat
+      Foreign.Compat
+      Foreign.ForeignPtr.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
+      Numeric.Natural.Compat
+      Prelude.Compat
       System.Environment.Compat
       System.Exit.Compat
+      System.IO.Compat
+      System.IO.Error.Compat
+      System.IO.Unsafe.Compat
       Text.Read.Compat
+      Text.Read.Lex.Compat
+      Type.Reflection.Compat
 
-test-suite spec
-  type:
-      exitcode-stdio-1.0
-  ghc-options:
-      -Wall
-  hs-source-dirs:
-      test
-  main-is:
-      Spec.hs
-  build-depends:
-      base > 4.0
-    , base-compat
-    , hspec >= 1.8
-    , QuickCheck
+      Control.Concurrent.Compat.Repl
+      Control.Concurrent.MVar.Compat.Repl
+      Control.Exception.Compat.Repl
+      Control.Monad.Compat.Repl
+      Control.Monad.Fail.Compat.Repl
+      Control.Monad.IO.Class.Compat.Repl
+      Control.Monad.ST.Lazy.Unsafe.Compat.Repl
+      Control.Monad.ST.Unsafe.Compat.Repl
+      Data.Bifoldable.Compat.Repl
+      Data.Bifoldable1.Compat.Repl
+      Data.Bifunctor.Compat.Repl
+      Data.Bitraversable.Compat.Repl
+      Data.Bits.Compat.Repl
+      Data.Bool.Compat.Repl
+      Data.Complex.Compat.Repl
+      Data.Either.Compat.Repl
+      Data.Foldable.Compat.Repl
+      Data.Foldable1.Compat.Repl
+      Data.Function.Compat.Repl
+      Data.Functor.Compat.Repl
+      Data.Functor.Compose.Compat.Repl
+      Data.Functor.Const.Compat.Repl
+      Data.Functor.Contravariant.Compat.Repl
+      Data.Functor.Identity.Compat.Repl
+      Data.Functor.Product.Compat.Repl
+      Data.Functor.Sum.Compat.Repl
+      Data.IORef.Compat.Repl
+      Data.List.Compat.Repl
+      Data.List.NonEmpty.Compat.Repl
+      Data.Monoid.Compat.Repl
+      Data.Proxy.Compat.Repl
+      Data.Ratio.Compat.Repl
+      Data.Semigroup.Compat.Repl
+      Data.STRef.Compat.Repl
+      Data.String.Compat.Repl
+      Data.Traversable.Compat.Repl
+      Data.Tuple.Compat.Repl
+      Data.Typeable.Compat.Repl
+      Data.Type.Coercion.Compat.Repl
+      Data.Type.Equality.Compat.Repl
+      Data.Version.Compat.Repl
+      Data.Void.Compat.Repl
+      Data.Word.Compat.Repl
+      Debug.Trace.Compat.Repl
+      Foreign.Compat.Repl
+      Foreign.ForeignPtr.Compat.Repl
+      Foreign.ForeignPtr.Safe.Compat.Repl
+      Foreign.ForeignPtr.Unsafe.Compat.Repl
+      Foreign.Marshal.Alloc.Compat.Repl
+      Foreign.Marshal.Array.Compat.Repl
+      Foreign.Marshal.Compat.Repl
+      Foreign.Marshal.Safe.Compat.Repl
+      Foreign.Marshal.Unsafe.Compat.Repl
+      Foreign.Marshal.Utils.Compat.Repl
+      Numeric.Compat.Repl
+      Numeric.Natural.Compat.Repl
+      Prelude.Compat.Repl
+      System.Environment.Compat.Repl
+      System.Exit.Compat.Repl
+      System.IO.Compat.Repl
+      System.IO.Error.Compat.Repl
+      System.IO.Unsafe.Compat.Repl
+      Text.Read.Compat.Repl
+      Text.Read.Lex.Compat.Repl
+      Type.Reflection.Compat.Repl
diff --git a/src/Control/Applicative/Compat.hs b/src/Control/Applicative/Compat.hs
deleted file mode 100644
--- a/src/Control/Applicative/Compat.hs
+++ /dev/null
@@ -1,22 +0,0 @@
-{-# OPTIONS_GHC -fno-warn-orphans #-}
-module Control.Applicative.Compat (
-  module Base
-, Const(..)
-, WrappedMonad(..)
-) where
-import Control.Applicative as Base
-
-#if !MIN_VERSION_base(4,7,0)
-import Data.Monoid (Monoid(..),mempty,mappend)
-import Control.Monad (Monad(..))
-import Data.Function ((.))
--- Added in base-4.7.0.0
-instance Monoid a => Monoid (Const a b) where
-    mempty = Const mempty
-    mappend (Const a) (Const b) = Const (mappend a b)
-
--- Added in base-4.7.0.0 (GHC Trac #8218)
-instance Monad m => Monad (WrappedMonad m) where
-    return = WrapMonad . return
-    a >>= f = WrapMonad (unwrapMonad a >>= unwrapMonad . f)
-#endif
diff --git a/src/Control/Concurrent/Compat.hs b/src/Control/Concurrent/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Concurrent/Compat.hs
@@ -0,0 +1,10 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE Trustworthy #-}
+module Control.Concurrent.Compat (
+  module Base
+, forkFinally
+, forkOSWithUnmask
+) where
+
+import Control.Concurrent as Base
diff --git a/src/Control/Concurrent/Compat/Repl.hs b/src/Control/Concurrent/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Concurrent/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Control.Concurrent.Compat"
+-- from a globally unique namespace.
+module Control.Concurrent.Compat.Repl (
+  module Control.Concurrent.Compat
+) where
+import "this" Control.Concurrent.Compat
diff --git a/src/Control/Concurrent/MVar/Compat.hs b/src/Control/Concurrent/MVar/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Concurrent/MVar/Compat.hs
@@ -0,0 +1,6 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+module Control.Concurrent.MVar.Compat (
+  module Base
+, withMVarMasked
+) where
+import Control.Concurrent.MVar as Base
diff --git a/src/Control/Concurrent/MVar/Compat/Repl.hs b/src/Control/Concurrent/MVar/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Concurrent/MVar/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Control.Concurrent.MVar.Compat"
+-- from a globally unique namespace.
+module Control.Concurrent.MVar.Compat.Repl (
+  module Control.Concurrent.MVar.Compat
+) where
+import "this" Control.Concurrent.MVar.Compat
diff --git a/src/Control/Exception/Compat.hs b/src/Control/Exception/Compat.hs
--- a/src/Control/Exception/Compat.hs
+++ b/src/Control/Exception/Compat.hs
@@ -1,13 +1,27 @@
-{-# LANGUAGE StandaloneDeriving #-}
-{-# OPTIONS_GHC -fno-warn-orphans #-}
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
+{-# LANGUAGE Trustworthy #-}
+#if MIN_VERSION_base(4,10,0)
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE RankNTypes #-}
+# if __GLASGOW_HASKELL__ < 806
+{-# LANGUAGE TypeInType #-}
+# endif
+#endif
 module Control.Exception.Compat (
   module Base
+, throw
 ) where
 
 import Control.Exception as Base
-import Control.Exception.ErrorCall.EqInstance ()
+#if MIN_VERSION_base(4,10,0) && !(MIN_VERSION_base(4,12,0))
+  hiding (throw)
+import GHC.Exts (RuntimeRep, TYPE, raise#)
 
-#if __GLASGOW_HASKELL__ <= 706
-import Prelude
-deriving instance Ord ErrorCall
+-- | Throw an exception.  Exceptions may be thrown from purely
+-- functional code, but may only be caught within the 'IO' monad.
+throw :: forall (r :: RuntimeRep). forall (a :: TYPE r). forall e.
+         Exception e => e -> a
+throw e = raise# (toException e)
 #endif
diff --git a/src/Control/Exception/Compat/Repl.hs b/src/Control/Exception/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Exception/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Control.Exception.Compat"
+-- from a globally unique namespace.
+module Control.Exception.Compat.Repl (
+  module Control.Exception.Compat
+) where
+import "this" Control.Exception.Compat
diff --git a/src/Control/Monad/Compat.hs b/src/Control/Monad/Compat.hs
--- a/src/Control/Monad/Compat.hs
+++ b/src/Control/Monad/Compat.hs
@@ -1,15 +1,11 @@
+{-# LANGUAGE NoImplicitPrelude #-}
 module Control.Monad.Compat (
   module Base
-, void
+, Monad
+, MonadFail
+, fail
+, MonadPlus(..)
 ) where
 
-import           Control.Monad as Base
-
-#if !MIN_VERSION_base(4,3,0)
-
-import           Prelude.Compat
-
--- | @'void' value@ discards or ignores the result of evaluation, such as the return value of an 'IO' action.
-void :: Functor f => f a -> f ()
-void = fmap (const ())
-#endif
+import Control.Monad as Base hiding (fail)
+import Control.Monad.Fail as Base
diff --git a/src/Control/Monad/Compat/Repl.hs b/src/Control/Monad/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Monad/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Control.Monad.Compat"
+-- from a globally unique namespace.
+module Control.Monad.Compat.Repl (
+  module Control.Monad.Compat
+) where
+import "this" Control.Monad.Compat
diff --git a/src/Control/Monad/Fail/Compat.hs b/src/Control/Monad/Fail/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Monad/Fail/Compat.hs
@@ -0,0 +1,6 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+module Control.Monad.Fail.Compat (
+  module Base
+) where
+
+import Control.Monad.Fail as Base
diff --git a/src/Control/Monad/Fail/Compat/Repl.hs b/src/Control/Monad/Fail/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Monad/Fail/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Control.Monad.Fail.Compat"
+-- from a globally unique namespace.
+module Control.Monad.Fail.Compat.Repl (
+  module Control.Monad.Fail.Compat
+) where
+import "this" Control.Monad.Fail.Compat
diff --git a/src/Control/Monad/IO/Class/Compat.hs b/src/Control/Monad/IO/Class/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Monad/IO/Class/Compat.hs
@@ -0,0 +1,6 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+module Control.Monad.IO.Class.Compat (
+  module Base
+) where
+
+import Control.Monad.IO.Class as Base
diff --git a/src/Control/Monad/IO/Class/Compat/Repl.hs b/src/Control/Monad/IO/Class/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Monad/IO/Class/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Control.Monad.IO.Class.Compat"
+-- from a globally unique namespace.
+module Control.Monad.IO.Class.Compat.Repl (
+  module Control.Monad.IO.Class.Compat
+) where
+import "this" Control.Monad.IO.Class.Compat
diff --git a/src/Control/Monad/ST/Lazy/Unsafe/Compat.hs b/src/Control/Monad/ST/Lazy/Unsafe/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Monad/ST/Lazy/Unsafe/Compat.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+module Control.Monad.ST.Lazy.Unsafe.Compat (
+  -- * Unsafe operations
+  unsafeInterleaveST
+, unsafeIOToST
+) where
+
+import Control.Monad.ST.Lazy.Unsafe (unsafeInterleaveST, unsafeIOToST)
diff --git a/src/Control/Monad/ST/Lazy/Unsafe/Compat/Repl.hs b/src/Control/Monad/ST/Lazy/Unsafe/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Monad/ST/Lazy/Unsafe/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Control.Monad.ST.Lazy.Unsafe.Compat"
+-- from a globally unique namespace.
+module Control.Monad.ST.Lazy.Unsafe.Compat.Repl (
+  module Control.Monad.ST.Lazy.Unsafe.Compat
+) where
+import "this" Control.Monad.ST.Lazy.Unsafe.Compat
diff --git a/src/Control/Monad/ST/Unsafe/Compat.hs b/src/Control/Monad/ST/Unsafe/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Monad/ST/Unsafe/Compat.hs
@@ -0,0 +1,9 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+module Control.Monad.ST.Unsafe.Compat (
+  -- * Unsafe operations
+  unsafeInterleaveST
+, unsafeIOToST
+, unsafeSTToIO
+) where
+
+import Control.Monad.ST.Unsafe (unsafeInterleaveST, unsafeIOToST, unsafeSTToIO)
diff --git a/src/Control/Monad/ST/Unsafe/Compat/Repl.hs b/src/Control/Monad/ST/Unsafe/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Monad/ST/Unsafe/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Control.Monad.ST.Unsafe.Compat"
+-- from a globally unique namespace.
+module Control.Monad.ST.Unsafe.Compat.Repl (
+  module Control.Monad.ST.Unsafe.Compat
+) where
+import "this" Control.Monad.ST.Unsafe.Compat
diff --git a/src/Data/Bifoldable/Compat.hs b/src/Data/Bifoldable/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Bifoldable/Compat.hs
@@ -0,0 +1,10 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
+module Data.Bifoldable.Compat (
+#if MIN_VERSION_base(4,10,0)
+  module Base
+#endif
+) where
+
+#if MIN_VERSION_base(4,10,0)
+import Data.Bifoldable as Base
+#endif
diff --git a/src/Data/Bifoldable/Compat/Repl.hs b/src/Data/Bifoldable/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Bifoldable/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Data.Bifoldable.Compat"
+-- from a globally unique namespace.
+module Data.Bifoldable.Compat.Repl (
+  module Data.Bifoldable.Compat
+) where
+import "this" Data.Bifoldable.Compat
diff --git a/src/Data/Bifoldable1/Compat.hs b/src/Data/Bifoldable1/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Bifoldable1/Compat.hs
@@ -0,0 +1,10 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
+module Data.Bifoldable1.Compat (
+#if MIN_VERSION_base(4,18,0)
+  module Base
+#endif
+) where
+
+#if MIN_VERSION_base(4,18,0)
+import Data.Bifoldable1 as Base
+#endif
diff --git a/src/Data/Bifoldable1/Compat/Repl.hs b/src/Data/Bifoldable1/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Bifoldable1/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Data.Bifoldable1.Compat"
+-- from a globally unique namespace.
+module Data.Bifoldable1.Compat.Repl (
+  module Data.Bifoldable1.Compat
+) where
+import "this" Data.Bifoldable1.Compat
diff --git a/src/Data/Bifunctor/Compat.hs b/src/Data/Bifunctor/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Bifunctor/Compat.hs
@@ -0,0 +1,6 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+module Data.Bifunctor.Compat (
+  module Base
+) where
+
+import Data.Bifunctor as Base
diff --git a/src/Data/Bifunctor/Compat/Repl.hs b/src/Data/Bifunctor/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Bifunctor/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Data.Bifunctor.Compat"
+-- from a globally unique namespace.
+module Data.Bifunctor.Compat.Repl (
+  module Data.Bifunctor.Compat
+) where
+import "this" Data.Bifunctor.Compat
diff --git a/src/Data/Bitraversable/Compat.hs b/src/Data/Bitraversable/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Bitraversable/Compat.hs
@@ -0,0 +1,72 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
+module Data.Bitraversable.Compat (
+#if MIN_VERSION_base(4,10,0)
+  module Base
+, firstA
+, secondA
+#endif
+) where
+
+#if MIN_VERSION_base(4,10,0)
+import Data.Bitraversable as Base
+
+# if !MIN_VERSION_base(4,21,0)
+import Prelude.Compat
+# endif
+
+# if !MIN_VERSION_base(4,21,0)
+-- | Traverses only over the first argument.
+--
+-- @'firstA' f ≡ 'bitraverse' f 'pure'@
+
+-- ==== __Examples__
+--
+-- Basic usage:
+--
+-- >>> firstA listToMaybe (Left [])
+-- Nothing
+--
+-- >>> firstA listToMaybe (Left [1, 2, 3])
+-- Just (Left 1)
+--
+-- >>> firstA listToMaybe (Right [4, 5])
+-- Just (Right [4, 5])
+--
+-- >>> firstA listToMaybe ([1, 2, 3], [4, 5])
+-- Just (1,[4, 5])
+--
+-- >>> firstA listToMaybe ([], [4, 5])
+-- Nothing
+
+-- @since 4.21.0.0
+firstA :: Bitraversable t => Applicative f => (a -> f c) -> t a b -> f (t c b)
+firstA f = bitraverse f pure
+
+-- | Traverses only over the second argument.
+--
+-- @'secondA' f ≡ 'bitraverse' 'pure' f@
+--
+-- ==== __Examples__
+--
+-- Basic usage:
+--
+-- >>> secondA (find odd) (Left [])
+-- Just (Left [])
+--
+-- >>> secondA (find odd) (Left [1, 2, 3])
+-- Just (Left [1,2,3])
+--
+-- >>> secondA (find odd) (Right [4, 5])
+-- Just (Right 5)
+--
+-- >>> secondA (find odd) ([1, 2, 3], [4, 5])
+-- Just ([1,2,3],5)
+--
+-- >>> secondA (find odd) ([1,2,3], [4])
+-- Nothing
+--
+-- @since 4.21.0.0
+secondA :: Bitraversable t => Applicative f => (b -> f c) -> t a b -> f (t a c)
+secondA f = bitraverse pure f
+# endif
+#endif
diff --git a/src/Data/Bitraversable/Compat/Repl.hs b/src/Data/Bitraversable/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Bitraversable/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Data.Bitraversable.Compat"
+-- from a globally unique namespace.
+module Data.Bitraversable.Compat.Repl (
+  module Data.Bitraversable.Compat
+) where
+import "this" Data.Bitraversable.Compat
diff --git a/src/Data/Bits/Compat.hs b/src/Data/Bits/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Bits/Compat.hs
@@ -0,0 +1,84 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
+{-# LANGUAGE BangPatterns, PatternGuards #-}
+module Data.Bits.Compat (
+  module Base
+, bitDefault
+, testBitDefault
+, popCountDefault
+, (.^.)
+, (.>>.)
+, (.<<.)
+, (!>>.)
+, (!<<.)
+, toIntegralSized
+, oneBits
+) where
+
+import Data.Bits as Base
+
+#if !(MIN_VERSION_base(4,17,0))
+import Prelude
+#endif
+
+#if !(MIN_VERSION_base(4,17,0))
+-- | Infix version of 'xor'.
+--
+-- /Since: 4.17/
+(.^.) :: (Bits a) => a -> a -> a
+(.^.) = xor
+
+infixl 6 .^.
+
+-- | Infix version of 'shiftR'.
+--
+-- /Since: 4.17/
+(.>>.) :: (Bits a) => a -> Int -> a
+(.>>.) = shiftR
+
+infixl 8 .>>.
+
+-- | Infix version of 'shiftL'.
+--
+-- /Since: 4.17/
+(.<<.) :: (Bits a) => a -> Int -> a
+(.<<.) = shiftL
+
+infixl 8 .<<.
+
+-- | Infix version of 'unsafeShiftR'.
+--
+-- /Since: 4.17/
+(!>>.) :: (Bits a) => a -> Int -> a
+(!>>.) = unsafeShiftR
+
+infixl 8 !>>.
+
+-- | Infix version of 'unsafeShiftL'.
+--
+-- /Since: 4.17/
+(!<<.) :: (Bits a) => a -> Int -> a
+(!<<.) = unsafeShiftL
+
+infixl 8 !<<.
+#endif
+
+#if !(MIN_VERSION_base(4,16,0))
+-- | A more concise version of @complement zeroBits@.
+--
+-- >>> complement (zeroBits :: Word) == (oneBits :: Word)
+-- True
+--
+-- >>> complement (oneBits :: Word) == (zeroBits :: Word)
+-- True
+--
+-- = Note
+--
+-- The constraint on 'oneBits' is arguably too strong. However, as some types
+-- (such as 'Natural') have undefined 'complement', this is the only safe
+-- choice.
+--
+-- /Since: 4.16/
+oneBits :: (FiniteBits a) => a
+oneBits = complement zeroBits
+{-# INLINE oneBits #-}
+#endif
diff --git a/src/Data/Bits/Compat/Repl.hs b/src/Data/Bits/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Bits/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Data.Bits.Compat"
+-- from a globally unique namespace.
+module Data.Bits.Compat.Repl (
+  module Data.Bits.Compat
+) where
+import "this" Data.Bits.Compat
diff --git a/src/Data/Bool/Compat.hs b/src/Data/Bool/Compat.hs
--- a/src/Data/Bool/Compat.hs
+++ b/src/Data/Bool/Compat.hs
@@ -1,23 +1,7 @@
+{-# LANGUAGE NoImplicitPrelude #-}
 module Data.Bool.Compat (
-   -- * Booleans
-   Bool(..),
-   -- ** Operations
-   (&&),
-   (||),
-   not,
-   otherwise,
-   bool,
-  ) where
-
-import Data.Bool
+  module Base
+, bool
+) where
 
-#if !MIN_VERSION_base(4,7,0)
--- | Case analysis for the 'Bool' type.
--- @bool a b p@ evaluates to @a@ when @p@ is @False@, and evaluates to @b@
--- when @p@ is @True@.
---
--- /Since: 4.7.0.0/
-bool :: a -> a -> Bool -> a
-bool f _ False = f
-bool _ t True  = t
-#endif
+import Data.Bool as Base
diff --git a/src/Data/Bool/Compat/Repl.hs b/src/Data/Bool/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Bool/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Data.Bool.Compat"
+-- from a globally unique namespace.
+module Data.Bool.Compat.Repl (
+  module Data.Bool.Compat
+) where
+import "this" Data.Bool.Compat
diff --git a/src/Data/Complex/Compat.hs b/src/Data/Complex/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Complex/Compat.hs
@@ -0,0 +1,6 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+module Data.Complex.Compat (
+  module Base
+) where
+
+import Data.Complex as Base
diff --git a/src/Data/Complex/Compat/Repl.hs b/src/Data/Complex/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Complex/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Data.Complex.Compat"
+-- from a globally unique namespace.
+module Data.Complex.Compat.Repl (
+  module Data.Complex.Compat
+) where
+import "this" Data.Complex.Compat
diff --git a/src/Data/Either/Compat.hs b/src/Data/Either/Compat.hs
--- a/src/Data/Either/Compat.hs
+++ b/src/Data/Either/Compat.hs
@@ -1,23 +1,45 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
 module Data.Either.Compat (
   module Base
 , isLeft
 , isRight
+, fromLeft
+, fromRight
 ) where
 import Data.Either as Base
 
-#if !MIN_VERSION_base(4,7,0)
-import Data.Bool (Bool(..))
--- | Return `True` if the given value is a `Left`-value, `False` otherwise.
+#if !(MIN_VERSION_base(4,10,0))
+-- | Return the contents of a 'Left'-value or a default value otherwise.
 --
--- /Since: 4.7.0.0/
-isLeft :: Either a b -> Bool
-isLeft (Left  _) = True
-isLeft (Right _) = False
+-- /Since: 4.10.0.0/
+--
+-- ==== __Examples__
+--
+-- Basic usage:
+--
+-- >>> fromLeft 1 (Left 3)
+-- 3
+-- >>> fromLeft 1 (Right "foo")
+-- 1
+--
+fromLeft :: a -> Either a b -> a
+fromLeft _ (Left a) = a
+fromLeft a _        = a
 
--- | Return `True` if the given value is a `Right`-value, `False` otherwise.
+-- | Return the contents of a 'Right'-value or a default value otherwise.
 --
--- /Since: 4.7.0.0/
-isRight :: Either a b -> Bool
-isRight (Left  _) = False
-isRight (Right _) = True
+-- /Since: 4.10.0.0/
+--
+-- ==== __Examples__
+--
+-- Basic usage:
+--
+-- >>> fromRight 1 (Right 3)
+-- 3
+-- >>> fromRight 1 (Left "foo")
+-- 1
+--
+fromRight :: b -> Either a b -> b
+fromRight _ (Right b) = b
+fromRight b _         = b
 #endif
diff --git a/src/Data/Either/Compat/Repl.hs b/src/Data/Either/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Either/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Data.Either.Compat"
+-- from a globally unique namespace.
+module Data.Either.Compat.Repl (
+  module Data.Either.Compat
+) where
+import "this" Data.Either.Compat
diff --git a/src/Data/Foldable/Compat.hs b/src/Data/Foldable/Compat.hs
--- a/src/Data/Foldable/Compat.hs
+++ b/src/Data/Foldable/Compat.hs
@@ -1,27 +1,33 @@
-{-# OPTIONS_GHC -fno-warn-orphans #-}
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
 module Data.Foldable.Compat (
   module Base
-, Foldable(..)
+#if !(MIN_VERSION_base(4,10,0))
+, maximumBy
+, minimumBy
+#endif
 ) where
-import Data.Foldable as Base
 
-#if !MIN_VERSION_base(4,7,0)
-import Data.Either (Either(..))
-import Data.Monoid (mempty)
-import Control.Applicative (Const(..))
-
-instance Foldable (Either a) where
-    foldMap _ (Left _) = mempty
-    foldMap f (Right y) = f y
-
-    foldr _ z (Left _) = z
-    foldr f z (Right y) = f y z
-
-instance Foldable ((,) a) where
-    foldMap f (_, y) = f y
+#if MIN_VERSION_base(4,10,0)
+import Data.Foldable as Base
+#else
+import Data.Foldable as Base hiding (maximumBy, minimumBy)
+import Prelude (Ordering(..))
+#endif
 
-    foldr f z (_, y) = f y z
+#if !(MIN_VERSION_base(4,10,0))
+-- | The largest element of a non-empty structure with respect to the
+-- given comparison function.
+maximumBy :: Foldable t => (a -> a -> Ordering) -> t a -> a
+maximumBy cmp = foldl1 max'
+  where max' x y = case cmp x y of
+                        GT -> x
+                        _  -> y
 
-instance Foldable (Const m) where
-    foldMap _ _ = mempty
+-- | The least element of a non-empty structure with respect to the
+-- given comparison function.
+minimumBy :: Foldable t => (a -> a -> Ordering) -> t a -> a
+minimumBy cmp = foldl1 min'
+  where min' x y = case cmp x y of
+                        GT -> y
+                        _  -> x
 #endif
diff --git a/src/Data/Foldable/Compat/Repl.hs b/src/Data/Foldable/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Foldable/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Data.Foldable.Compat"
+-- from a globally unique namespace.
+module Data.Foldable.Compat.Repl (
+  module Data.Foldable.Compat
+) where
+import "this" Data.Foldable.Compat
diff --git a/src/Data/Foldable1/Compat.hs b/src/Data/Foldable1/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Foldable1/Compat.hs
@@ -0,0 +1,10 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
+module Data.Foldable1.Compat (
+#if MIN_VERSION_base(4,18,0)
+  module Base
+#endif
+) where
+
+#if MIN_VERSION_base(4,18,0)
+import Data.Foldable1 as Base
+#endif
diff --git a/src/Data/Foldable1/Compat/Repl.hs b/src/Data/Foldable1/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Foldable1/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Data.Foldable1.Compat"
+-- from a globally unique namespace.
+module Data.Foldable1.Compat.Repl (
+  module Data.Foldable1.Compat
+) where
+import "this" Data.Foldable1.Compat
diff --git a/src/Data/Function/Compat.hs b/src/Data/Function/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Function/Compat.hs
@@ -0,0 +1,40 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
+module Data.Function.Compat (
+  module Base
+, (&)
+, applyWhen
+) where
+import Data.Function as Base
+
+#if !(MIN_VERSION_base(4,18,0))
+import Prelude.Compat
+#endif
+
+#if !(MIN_VERSION_base(4,18,0))
+-- | 'applyWhen' applies a function to a value if a condition is true,
+-- otherwise, it returns the value unchanged.
+--
+-- It is equivalent to @'flip' ('Data.Bool.bool' 'id')@.
+--
+-- Algebraic properties:
+--
+-- * @applyWhen 'True' = 'id'@
+--
+-- * @applyWhen 'False' f = 'id'@
+--
+-- /Since: 4.18.0.0/
+applyWhen :: Bool -> (a -> a) -> a -> a
+applyWhen True  f x = f x
+applyWhen False _ x = x
+-- Proofs:
+--
+-- flip bool id = \q f -> bool id f q
+-- = \f q -> case q of
+--     True -> f = \x -> f x
+--     False -> id = \x -> x ∎
+--
+-- applyWhen True = \f x -> f x
+-- = \f -> \x -> f x = \f -> f = id ∎
+--
+-- applyWhen False f = \x -> x = id ∎
+#endif
diff --git a/src/Data/Function/Compat/Repl.hs b/src/Data/Function/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Function/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Data.Function.Compat"
+-- from a globally unique namespace.
+module Data.Function.Compat.Repl (
+  module Data.Function.Compat
+) where
+import "this" Data.Function.Compat
diff --git a/src/Data/Functor/Compat.hs b/src/Data/Functor/Compat.hs
--- a/src/Data/Functor/Compat.hs
+++ b/src/Data/Functor/Compat.hs
@@ -1,20 +1,49 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
 module Data.Functor.Compat (
   module Base
+, Functor(..)
 , ($>)
 , void
+, (<&>)
+, unzip
 ) where
 import Data.Functor as Base
 
-#if !MIN_VERSION_base(4,7,0)
-import Control.Monad.Compat (void)
-import Data.Function (flip)
-
-infixl 4 $>
+#if !(MIN_VERSION_base(4,19,0))
+import Data.Tuple (fst, snd)
+#endif
 
--- | Flipped version of '$>'.
+#if !(MIN_VERSION_base(4,11,0))
+-- | Flipped version of '<$>'.
 --
--- /Since: 4.7.0.0/
-($>) :: Functor f => f a -> b -> f b
-($>) = flip (<$)
+-- @
+-- ('<&>') = 'flip' 'fmap'
+-- @
+--
+-- /Since: 4.11.0.0/
+--
+-- ==== __Examples__
+-- Apply @(+1)@ to a list, a 'Data.Maybe.Just' and a 'Data.Either.Right':
+--
+-- >>> Just 2 <&> (+1)
+-- Just 3
+--
+-- >>> [1,2,3] <&> (+1)
+-- [2,3,4]
+--
+-- >>> Right 3 <&> (+1)
+-- Right 4
+--
+(<&>) :: Functor f => f a -> (a -> b) -> f b
+as <&> f = f <$> as
 
+infixl 1 <&>
+#endif
+
+#if !(MIN_VERSION_base(4,19,0))
+-- | Generalization of @Data.List.@'Data.List.unzip'.
+--
+-- /Since: 4.19.0.0/
+unzip :: Functor f => f (a, b) -> (f a, f b)
+unzip xs = (fst <$> xs, snd <$> xs)
 #endif
diff --git a/src/Data/Functor/Compat/Repl.hs b/src/Data/Functor/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Functor/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Data.Functor.Compat"
+-- from a globally unique namespace.
+module Data.Functor.Compat.Repl (
+  module Data.Functor.Compat
+) where
+import "this" Data.Functor.Compat
diff --git a/src/Data/Functor/Compose/Compat.hs b/src/Data/Functor/Compose/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Functor/Compose/Compat.hs
@@ -0,0 +1,6 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+module Data.Functor.Compose.Compat (
+  module Base
+) where
+
+import Data.Functor.Compose as Base
diff --git a/src/Data/Functor/Compose/Compat/Repl.hs b/src/Data/Functor/Compose/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Functor/Compose/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Data.Functor.Compose.Compat"
+-- from a globally unique namespace.
+module Data.Functor.Compose.Compat.Repl (
+  module Data.Functor.Compose.Compat
+) where
+import "this" Data.Functor.Compose.Compat
diff --git a/src/Data/Functor/Const/Compat.hs b/src/Data/Functor/Const/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Functor/Const/Compat.hs
@@ -0,0 +1,4 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
+module Data.Functor.Const.Compat (Const(..)) where
+
+import Control.Applicative (Const(..))
diff --git a/src/Data/Functor/Const/Compat/Repl.hs b/src/Data/Functor/Const/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Functor/Const/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Data.Functor.Const.Compat"
+-- from a globally unique namespace.
+module Data.Functor.Const.Compat.Repl (
+  module Data.Functor.Const.Compat
+) where
+import "this" Data.Functor.Const.Compat
diff --git a/src/Data/Functor/Contravariant/Compat.hs b/src/Data/Functor/Contravariant/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Functor/Contravariant/Compat.hs
@@ -0,0 +1,10 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
+module Data.Functor.Contravariant.Compat (
+#if MIN_VERSION_base(4,12,0)
+  module Base
+#endif
+) where
+
+#if MIN_VERSION_base(4,12,0)
+import Data.Functor.Contravariant as Base
+#endif
diff --git a/src/Data/Functor/Contravariant/Compat/Repl.hs b/src/Data/Functor/Contravariant/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Functor/Contravariant/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Data.Functor.Contravariant.Compat"
+-- from a globally unique namespace.
+module Data.Functor.Contravariant.Compat.Repl (
+  module Data.Functor.Contravariant.Compat
+) where
+import "this" Data.Functor.Contravariant.Compat
diff --git a/src/Data/Functor/Identity/Compat.hs b/src/Data/Functor/Identity/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Functor/Identity/Compat.hs
@@ -0,0 +1,6 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+module Data.Functor.Identity.Compat (
+  module Base
+) where
+
+import Data.Functor.Identity as Base
diff --git a/src/Data/Functor/Identity/Compat/Repl.hs b/src/Data/Functor/Identity/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Functor/Identity/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Data.Functor.Identity.Compat"
+-- from a globally unique namespace.
+module Data.Functor.Identity.Compat.Repl (
+  module Data.Functor.Identity.Compat
+) where
+import "this" Data.Functor.Identity.Compat
diff --git a/src/Data/Functor/Product/Compat.hs b/src/Data/Functor/Product/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Functor/Product/Compat.hs
@@ -0,0 +1,6 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+module Data.Functor.Product.Compat (
+  module Base
+) where
+
+import Data.Functor.Product as Base
diff --git a/src/Data/Functor/Product/Compat/Repl.hs b/src/Data/Functor/Product/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Functor/Product/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Data.Functor.Product.Compat"
+-- from a globally unique namespace.
+module Data.Functor.Product.Compat.Repl (
+  module Data.Functor.Product.Compat
+) where
+import "this" Data.Functor.Product.Compat
diff --git a/src/Data/Functor/Sum/Compat.hs b/src/Data/Functor/Sum/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Functor/Sum/Compat.hs
@@ -0,0 +1,6 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+module Data.Functor.Sum.Compat (
+  module Base
+) where
+
+import Data.Functor.Sum as Base
diff --git a/src/Data/Functor/Sum/Compat/Repl.hs b/src/Data/Functor/Sum/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Functor/Sum/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Data.Functor.Sum.Compat"
+-- from a globally unique namespace.
+module Data.Functor.Sum.Compat.Repl (
+  module Data.Functor.Sum.Compat
+) where
+import "this" Data.Functor.Sum.Compat
diff --git a/src/Data/IORef/Compat.hs b/src/Data/IORef/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/IORef/Compat.hs
@@ -0,0 +1,9 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+module Data.IORef.Compat (
+  module Base
+, modifyIORef'
+, atomicModifyIORef'
+, atomicWriteIORef
+) where
+
+import Data.IORef as Base
diff --git a/src/Data/IORef/Compat/Repl.hs b/src/Data/IORef/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/IORef/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Data.IORef.Compat"
+-- from a globally unique namespace.
+module Data.IORef.Compat.Repl (
+  module Data.IORef.Compat
+) where
+import "this" Data.IORef.Compat
diff --git a/src/Data/List/Compat.hs b/src/Data/List/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/List/Compat.hs
@@ -0,0 +1,237 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE Trustworthy #-}
+module Data.List.Compat (
+  module Base
+
+#if !(MIN_VERSION_base(4,21,0))
+, compareLength
+, inits1
+, tails1
+#endif
+
+#if MIN_VERSION_base(4,18,0) && !(MIN_VERSION_base(4,20,0))
+, List
+#endif
+
+#if !(MIN_VERSION_base(4,19,0))
+, (!?)
+, unsnoc
+#endif
+
+#if !(MIN_VERSION_base(4,15,0))
+, singleton
+#endif
+
+#if !(MIN_VERSION_base(4,11,0))
+, iterate'
+#endif
+) where
+
+import Data.List as Base
+
+#if MIN_VERSION_base(4,18,0) && !(MIN_VERSION_base(4,20,0))
+import GHC.List (List)
+#endif
+
+#if !(MIN_VERSION_base(4,21,0))
+import Data.List.NonEmpty (NonEmpty(..))
+import GHC.Exts (build)
+import Prelude.Compat hiding (foldr, null)
+#endif
+
+#if !(MIN_VERSION_base(4,11,0))
+-- | 'iterate\'' is the strict version of 'iterate'.
+--
+-- It ensures that the result of each application of force to weak head normal
+-- form before proceeding.
+{-# NOINLINE [1] iterate' #-}
+iterate' :: (a -> a) -> a -> [a]
+iterate' f x =
+    let x' = f x
+    in x' `seq` (x : iterate' f x')
+
+{-# INLINE [0] iterate'FB #-} -- See Note [Inline FB functions]
+iterate'FB :: (a -> b -> b) -> (a -> a) -> a -> b
+iterate'FB c f x0 = go x0
+  where go x =
+            let x' = f x
+            in x' `seq` (x `c` go x')
+
+{-# RULES
+"iterate'"    [~1] forall f x.   iterate' f x = build (\c _n -> iterate'FB c f x)
+"iterate'FB"  [1]                iterate'FB (:) = iterate'
+ #-}
+#endif
+
+#if !(MIN_VERSION_base(4,15,0))
+-- | Produce singleton list.
+--
+-- >>> singleton True
+-- [True]
+--
+-- /Since: 4.14.0.0/
+--
+singleton :: a -> [a]
+singleton x = [x]
+#endif
+
+#if !(MIN_VERSION_base(4,19,0))
+infixl 9 !?
+-- | List index (subscript) operator, starting from 0. Returns 'Nothing'
+-- if the index is out of bounds
+--
+-- >>> ['a', 'b', 'c'] !? 0
+-- Just 'a'
+-- >>> ['a', 'b', 'c'] !? 2
+-- Just 'c'
+-- >>> ['a', 'b', 'c'] !? 3
+-- Nothing
+-- >>> ['a', 'b', 'c'] !? (-1)
+-- Nothing
+--
+-- This is the total variant of the partial '!!' operator.
+--
+-- WARNING: This function takes linear time in the index.
+(!?) :: [a] -> Int -> Maybe a
+
+{-# INLINABLE (!?) #-}
+xs !? n
+  | n < 0     = Nothing
+  | otherwise = foldr (\x r k -> case k of
+                                   0 -> Just x
+                                   _ -> r (k-1)) (const Nothing) xs n
+
+-- | \(\mathcal{O}(n)\). Decompose a list into 'init' and 'last'.
+--
+-- * If the list is empty, returns 'Nothing'.
+-- * If the list is non-empty, returns @'Just' (xs, x)@,
+-- where @xs@ is the 'init'ial part of the list and @x@ is its 'last' element.
+--
+-- /Since: 4.19.0.0/
+--
+-- >>> unsnoc []
+-- Nothing
+-- >>> unsnoc [1]
+-- Just ([],1)
+-- >>> unsnoc [1, 2, 3]
+-- Just ([1,2],3)
+--
+-- Laziness:
+--
+-- >>> fst <$> unsnoc [undefined]
+-- Just []
+-- >>> head . fst <$> unsnoc (1 : undefined)
+-- Just *** Exception: Prelude.undefined
+-- >>> head . fst <$> unsnoc (1 : 2 : undefined)
+-- Just 1
+--
+-- 'unsnoc' is dual to 'uncons': for a finite list @xs@
+--
+-- > unsnoc xs = (\(hd, tl) -> (reverse tl, hd)) <$> uncons (reverse xs)
+--
+unsnoc :: [a] -> Maybe ([a], a)
+-- The lazy pattern ~(a, b) is important to be productive on infinite lists
+-- and not to be prone to stack overflows.
+-- Expressing the recursion via 'foldr' provides for list fusion.
+unsnoc = foldr (\x -> Just . maybe ([], x) (\(~(a, b)) -> (x : a, b))) Nothing
+{-# INLINABLE unsnoc #-}
+#endif
+
+#if !(MIN_VERSION_base(4,21,0))
+-- | Use 'compareLength' @xs@ @n@ as a safer and faster alternative
+-- to 'compare' ('length' @xs@) @n@. Similarly, it's better
+-- to write @compareLength xs 10 == LT@ instead of @length xs < 10@.
+--
+-- While 'length' would force and traverse
+-- the entire spine of @xs@ (which could even diverge if @xs@ is infinite),
+-- 'compareLength' traverses at most @n@ elements to determine its result.
+--
+-- >>> compareLength [] 0
+-- EQ
+-- >>> compareLength [] 1
+-- LT
+-- >>> compareLength ['a'] 1
+-- EQ
+-- >>> compareLength ['a', 'b'] 1
+-- GT
+-- >>> compareLength [0..] 100
+-- GT
+-- >>> compareLength undefined (-1)
+-- GT
+-- >>> compareLength ('a' : undefined) 0
+-- GT
+--
+-- @since 4.21.0.0
+--
+compareLength :: [a] -> Int -> Ordering
+compareLength xs n
+  | n < 0 = GT
+  | otherwise = foldr
+    (\_ f m -> if m > 0 then f (m - 1) else GT)
+    (\m -> if m > 0 then LT else EQ)
+    xs
+    n
+
+inits1, tails1 :: [a] -> [NonEmpty a]
+
+-- | The 'inits1' function returns all non-empty initial segments of the
+-- argument, shortest first.
+--
+-- @since 4.21.0.0
+--
+-- ==== __Laziness__
+--
+-- Note that 'inits1' has the following strictness property:
+-- @inits1 (xs ++ _|_) = inits1 xs ++ _|_@
+--
+-- In particular,
+-- @inits1 _|_ = _|_@
+--
+-- ==== __Examples__
+--
+-- >>> inits1 "abc"
+-- ['a' :| "",'a' :| "b",'a' :| "bc"]
+--
+-- >>> inits1 []
+-- []
+--
+-- inits1 is productive on infinite lists:
+--
+-- >>> take 3 $ inits1 [1..]
+-- [1 :| [],1 :| [2],1 :| [2,3]]
+inits1 [] = []
+inits1 (x : xs) = map (x :|) (inits xs)
+
+-- | \(\mathcal{O}(n)\). The 'tails1' function returns all non-empty final
+-- segments of the argument, longest first.
+--
+-- @since 4.21.0.0
+--
+-- ==== __Laziness__
+--
+-- Note that 'tails1' has the following strictness property:
+-- @tails1 _|_ = _|_@
+--
+-- >>> tails1 undefined
+-- *** Exception: Prelude.undefined
+--
+-- >>> drop 1 (tails1 [undefined, 1, 2])
+-- [1 :| [2],2 :| []]
+--
+-- ==== __Examples__
+--
+-- >>> tails1 "abc"
+-- ['a' :| "bc",'b' :| "c",'c' :| ""]
+--
+-- >>> tails1 [1, 2, 3]
+-- [1 :| [2,3],2 :| [3],3 :| []]
+--
+-- >>> tails1 []
+-- []
+{-# INLINABLE tails1 #-}
+tails1 lst = build (\c n ->
+  let tails1Go [] = n
+      tails1Go (x : xs) = (x :| xs) `c` tails1Go xs
+  in tails1Go lst)
+#endif
diff --git a/src/Data/List/Compat/Repl.hs b/src/Data/List/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/List/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Data.List.Compat"
+-- from a globally unique namespace.
+module Data.List.Compat.Repl (
+  module Data.List.Compat
+) where
+import "this" Data.List.Compat
diff --git a/src/Data/List/NonEmpty/Compat.hs b/src/Data/List/NonEmpty/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/List/NonEmpty/Compat.hs
@@ -0,0 +1,290 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
+-- | This backports the modern "Data.Semigroup" interface back to
+-- @base-4.9@/GHC 8.0.
+module Data.List.NonEmpty.Compat (
+  -- * The type of non-empty streams
+    NonEmpty(..)
+
+  -- * Non-empty stream transformations
+  , map
+  , intersperse
+  , scanl
+  , scanr
+  , scanl1
+  , scanr1
+  , transpose
+  , sortBy
+  , sortWith
+  -- * Basic functions
+  , length
+  , compareLength
+  , head
+  , tail
+  , last
+  , init
+  , singleton
+  , (<|), cons
+  , uncons
+  , unfoldr
+  , sort
+  , sortOn
+  , reverse
+  , inits
+  , inits1
+  , tails
+  , tails1
+  , append
+  , appendList
+  , prependList
+  -- * Building streams
+  , iterate
+  , repeat
+  , cycle
+  , unfold
+  , insert
+  , some1
+  -- * Extracting sublists
+  , take
+  , drop
+  , splitAt
+  , takeWhile
+  , dropWhile
+  , span
+  , break
+  , filter
+  , partition
+  , group
+  , groupBy
+  , groupWith
+  , groupAllWith
+  , group1
+  , groupBy1
+  , groupWith1
+  , groupAllWith1
+  , permutations
+  , permutations1
+  -- * Sublist predicates
+  , isPrefixOf
+  -- * \"Set\" operations
+  , nub
+  , nubBy
+  -- * Indexing streams
+  , (!!)
+  -- * Zipping and unzipping streams
+  , zip
+  , zipWith
+  , unzip
+  -- * Converting to and from a list
+  , fromList
+  , toList
+  , nonEmpty
+  , xor
+) where
+
+import Data.List.NonEmpty
+#if !(MIN_VERSION_base(4,22,0))
+  hiding (unzip)
+#endif
+
+#if !(MIN_VERSION_base(4,20,0))
+import Prelude.Compat ((.))
+
+import qualified Data.List.Compat as List
+#endif
+
+#if !(MIN_VERSION_base(4,22,0))
+import qualified Prelude.Compat as Prelude
+#endif
+
+#if !(MIN_VERSION_base(4,21,0))
+import Prelude.Compat (Int, Num(..), Ord(..), Ordering(..), otherwise)
+
+import qualified Data.Foldable.Compat as Foldable
+#endif
+
+#if !(MIN_VERSION_base(4,15,0))
+-- | Construct a 'NonEmpty' list from a single element.
+--
+-- /Since: 4.15/
+singleton :: a -> NonEmpty a
+singleton a = a :| []
+#endif
+
+#if !(MIN_VERSION_base(4,16,0))
+-- | A monomorphic version of 'Prelude.<>' for 'NonEmpty'.
+--
+-- >>> append (1 :| []) (2 :| [3])
+-- 1 :| [2,3]
+--
+-- /Since: 4.16/
+append :: NonEmpty a -> NonEmpty a -> NonEmpty a
+append = (Prelude.<>)
+
+-- | Attach a list at the end of a 'NonEmpty'.
+--
+-- >>> appendList (1 :| [2,3]) []
+-- 1 :| [2,3]
+--
+-- >>> appendList (1 :| [2,3]) [4,5]
+-- 1 :| [2,3,4,5]
+--
+-- /Since: 4.16/
+appendList :: NonEmpty a -> [a] -> NonEmpty a
+appendList (x :| xs) ys = x :| xs Prelude.<> ys
+
+-- | Attach a list at the beginning of a 'NonEmpty'.
+--
+-- >>> prependList [] (1 :| [2,3])
+-- 1 :| [2,3]
+--
+-- >>> prependList [negate 1, 0] (1 :| [2, 3])
+-- -1 :| [0,1,2,3]
+--
+-- /Since: 4.16/
+prependList :: [a] -> NonEmpty a -> NonEmpty a
+prependList ls ne = case ls of
+  [] -> ne
+  (x : xs) -> x :| xs Prelude.<> toList ne
+#endif
+
+#if !(MIN_VERSION_base(4,18,0))
+-- | The 'inits1' function takes a 'NonEmpty' stream @xs@ and returns all the
+-- 'NonEmpty' finite prefixes of @xs@, starting with the shortest.
+--
+-- > inits1 (1 :| [2,3]) == (1 :| []) :| [1 :| [2], 1 :| [2,3]]
+-- > inits1 (1 :| []) == (1 :| []) :| []
+--
+-- /Since: 4.18/
+inits1 :: NonEmpty a -> NonEmpty (NonEmpty a)
+inits1 =
+  -- fromList is an unsafe function, but this usage should be safe, since:
+  -- - `inits xs = [[], ..., init (init xs), init xs, xs]`
+  -- - If `xs` is nonempty, it follows that `inits xs` contains at least one nonempty
+  --   list, since `last (inits xs) = xs`.
+  -- - The only empty element of `inits xs` is the first one (by the definition of `inits`)
+  -- - Therefore, if we take all but the first element of `inits xs` i.e.
+  --   `tail (inits xs)`, we have a nonempty list of nonempty lists
+  fromList . Prelude.map fromList . List.tail . List.inits . Foldable.toList
+
+-- | The 'tails1' function takes a 'NonEmpty' stream @xs@ and returns all the
+-- non-empty suffixes of @xs@, starting with the longest.
+--
+-- > tails1 (1 :| [2,3]) == (1 :| [2,3]) :| [2 :| [3], 3 :| []]
+-- > tails1 (1 :| []) == (1 :| []) :| []
+--
+-- /Since: 4.18/
+tails1 :: NonEmpty a -> NonEmpty (NonEmpty a)
+tails1 =
+  -- fromList is an unsafe function, but this usage should be safe, since:
+  -- - `tails xs = [xs, tail xs, tail (tail xs), ..., []]`
+  -- - If `xs` is nonempty, it follows that `tails xs` contains at least one nonempty
+  --   list, since `head (tails xs) = xs`.
+  -- - The only empty element of `tails xs` is the last one (by the definition of `tails`)
+  -- - Therefore, if we take all but the last element of `tails xs` i.e.
+  --   `init (tails xs)`, we have a nonempty list of nonempty lists
+  fromList . Prelude.map fromList . List.init . List.tails . Foldable.toList
+#endif
+
+#if !(MIN_VERSION_base(4,20,0))
+-- | The 'permutations' function returns the list of all permutations of the argument.
+--
+-- /Since: 4.20.0.0/
+permutations            :: [a] -> NonEmpty [a]
+permutations xs0        =  xs0 :| perms xs0 []
+  where
+    perms []     _  = []
+    perms (t:ts) is = List.foldr interleave (perms ts (t:is)) (permutations is)
+      where interleave    xs     r = let (_,zs) = interleave' Prelude.id xs r in zs
+            interleave' _ []     r = (ts, r)
+            interleave' f (y:ys) r = let (us,zs) = interleave' (f . (y:)) ys r
+                                     in  (y:us, f (t:y:us) : zs)
+-- The implementation of 'permutations' is adopted from 'GHC.Internal.Data.List.permutations',
+-- see there for discussion and explanations.
+
+-- | 'permutations1' operates like 'permutations', but uses the knowledge that its input is
+-- non-empty to produce output where every element is non-empty.
+--
+-- > permutations1 = fmap fromList . permutations . toList
+--
+-- /Since: 4.20.0.0/
+permutations1 :: NonEmpty a -> NonEmpty (NonEmpty a)
+permutations1 xs = fromList Prelude.<$> permutations (toList xs)
+
+-- | Sort a 'NonEmpty' on a user-supplied projection of its elements.
+-- See 'List.sortOn' for more detailed information.
+--
+-- ==== __Examples__
+--
+-- >>> sortOn fst $ (2, "world") :| [(4, "!"), (1, "Hello")]
+-- (1,"Hello") :| [(2,"world"),(4,"!")]
+--
+-- >>> sortOn length $ "jim" :| ["creed", "pam", "michael", "dwight", "kevin"]
+-- "jim" :| ["pam","creed","kevin","dwight","michael"]
+--
+-- ==== __Performance notes__
+--
+-- This function minimises the projections performed, by materialising
+-- the projections in an intermediate list.
+--
+-- For trivial projections, you should prefer using 'sortBy' with
+-- 'comparing', for example:
+--
+-- >>> sortBy (comparing fst) $ (3, 1) :| [(2, 2), (1, 3)]
+-- (1,3) :| [(2,2),(3,1)]
+--
+-- Or, for the exact same API as 'sortOn', you can use `sortBy . comparing`:
+--
+-- >>> (sortBy . comparing) fst $ (3, 1) :| [(2, 2), (1, 3)]
+-- (1,3) :| [(2,2),(3,1)]
+--
+-- 'sortWith' is an alias for `sortBy . comparing`.
+--
+-- /Since: 4.20.0.0/
+sortOn :: Prelude.Ord b => (a -> b) -> NonEmpty a -> NonEmpty a
+sortOn f = lift (List.sortOn f)
+
+-- | Lift list operations to work on a 'NonEmpty' stream.
+--
+-- /Beware/: If the provided function returns an empty list,
+-- this will raise an error.
+lift :: Foldable.Foldable f => ([a] -> [b]) -> f a -> NonEmpty b
+lift f = fromList . f . Foldable.toList
+#endif
+
+#if !(MIN_VERSION_base(4,21,0))
+-- | Use 'compareLength' @xs@ @n@ as a safer and faster alternative
+-- to 'compare' ('length' @xs@) @n@. Similarly, it's better
+-- to write @compareLength xs 10 == LT@ instead of @length xs < 10@.
+--
+-- While 'length' would force and traverse
+-- the entire spine of @xs@ (which could even diverge if @xs@ is infinite),
+-- 'compareLength' traverses at most @n@ elements to determine its result.
+--
+-- >>> compareLength ('a' :| []) 1
+-- EQ
+-- >>> compareLength ('a' :| ['b']) 3
+-- LT
+-- >>> compareLength (0 :| [1..]) 100
+-- GT
+-- >>> compareLength undefined 0
+-- GT
+-- >>> compareLength ('a' :| 'b' : undefined) 1
+-- GT
+--
+-- @since 4.21.0.0
+--
+compareLength :: NonEmpty a -> Int -> Ordering
+compareLength xs n
+  | n < 1 = GT
+  | otherwise = Foldable.foldr
+    (\_ f m -> if m > 0 then f (m - 1) else GT)
+    (\m -> if m > 0 then LT else EQ)
+    xs
+    n
+#endif
+
+#if !(MIN_VERSION_base(4,22,0))
+-- | The 'unzip' function is the inverse of the 'zip' function.
+unzip :: NonEmpty (a, b) -> (NonEmpty a, NonEmpty b)
+unzip xs = (Prelude.fst Prelude.<$> xs, Prelude.snd Prelude.<$> xs)
+#endif
diff --git a/src/Data/List/NonEmpty/Compat/Repl.hs b/src/Data/List/NonEmpty/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/List/NonEmpty/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Data.List.NonEmpty.Compat"
+-- from a globally unique namespace.
+module Data.List.NonEmpty.Compat.Repl (
+  module Data.List.NonEmpty.Compat
+) where
+import "this" Data.List.NonEmpty.Compat
diff --git a/src/Data/Monoid/Compat.hs b/src/Data/Monoid/Compat.hs
--- a/src/Data/Monoid/Compat.hs
+++ b/src/Data/Monoid/Compat.hs
@@ -1,30 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
 module Data.Monoid.Compat (
-        -- * Monoid typeclass
-        Monoid(..),
-        (<>),
-        Dual(..),
-        Endo(..),
-        -- * Bool wrappers
-        All(..),
-        Any(..),
-        -- * Num wrappers
-        Sum(..),
-        Product(..),
-        -- * Maybe wrappers
-        -- $MaybeExamples
-        First(..),
-        Last(..)
-  ) where
-
-import Data.Monoid as Base
-
-#if !MIN_VERSION_base(4,5,0)
-infixr 6 <>
+  module Base
+, (<>)
+) where
 
--- | An infix synonym for 'mappend'.
---
--- /Since: 4.5.0.0/
-(<>) :: Monoid m => m -> m -> m
-(<>) = mappend
-{-# INLINE (<>) #-}
-#endif
+import Data.Monoid as Base hiding ((<>))
+import Data.Semigroup ((<>))
diff --git a/src/Data/Monoid/Compat/Repl.hs b/src/Data/Monoid/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Monoid/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Data.Monoid.Compat"
+-- from a globally unique namespace.
+module Data.Monoid.Compat.Repl (
+  module Data.Monoid.Compat
+) where
+import "this" Data.Monoid.Compat
diff --git a/src/Data/Proxy/Compat.hs b/src/Data/Proxy/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Proxy/Compat.hs
@@ -0,0 +1,23 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
+module Data.Proxy.Compat (
+  module Base,
+  asProxyTypeOf
+) where
+
+#if MIN_VERSION_base(4,10,0)
+import Data.Proxy as Base
+#else
+import Data.Proxy as Base hiding (asProxyTypeOf)
+#endif
+
+#if !(MIN_VERSION_base(4,10,0))
+import Prelude (const)
+
+-- | 'asProxyTypeOf' is a type-restricted version of 'const'.
+-- It is usually used as an infix operator, and its typing forces its first
+-- argument (which is usually overloaded) to have the same type as the tag
+-- of the second.
+asProxyTypeOf :: a -> proxy a -> a
+asProxyTypeOf = const
+{-# INLINE asProxyTypeOf #-}
+#endif
diff --git a/src/Data/Proxy/Compat/Repl.hs b/src/Data/Proxy/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Proxy/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Data.Proxy.Compat"
+-- from a globally unique namespace.
+module Data.Proxy.Compat.Repl (
+  module Data.Proxy.Compat
+) where
+import "this" Data.Proxy.Compat
diff --git a/src/Data/Ratio/Compat.hs b/src/Data/Ratio/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Ratio/Compat.hs
@@ -0,0 +1,6 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+module Data.Ratio.Compat (
+  module Base
+) where
+
+import Data.Ratio as Base
diff --git a/src/Data/Ratio/Compat/Repl.hs b/src/Data/Ratio/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Ratio/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Data.Ratio.Compat"
+-- from a globally unique namespace.
+module Data.Ratio.Compat.Repl (
+  module Data.Ratio.Compat
+) where
+import "this" Data.Ratio.Compat
diff --git a/src/Data/STRef/Compat.hs b/src/Data/STRef/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/STRef/Compat.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE Trustworthy #-}
+module Data.STRef.Compat (
+  module Base
+, modifySTRef'
+) where
+
+import Data.STRef as Base
diff --git a/src/Data/STRef/Compat/Repl.hs b/src/Data/STRef/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/STRef/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Data.STRef.Compat"
+-- from a globally unique namespace.
+module Data.STRef.Compat.Repl (
+  module Data.STRef.Compat
+) where
+import "this" Data.STRef.Compat
diff --git a/src/Data/Semigroup/Compat.hs b/src/Data/Semigroup/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Semigroup/Compat.hs
@@ -0,0 +1,32 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+-- | This backports the modern "Data.Semigroup" interface back to
+-- @base-4.9@/GHC 8.0.
+module Data.Semigroup.Compat (
+    Semigroup(..)
+  , stimesMonoid
+  , stimesIdempotent
+  , stimesIdempotentMonoid
+  , mtimesDefault
+  -- * Semigroups
+  , Min(..)
+  , Max(..)
+  , First(..)
+  , Last(..)
+  , WrappedMonoid(..)
+  -- * Re-exported monoids from Data.Monoid
+  , Dual(..)
+  , Endo(..)
+  , All(..)
+  , Any(..)
+  , Sum(..)
+  , Product(..)
+  -- * Difference lists of a semigroup
+  , diff
+  , cycle1
+  -- * ArgMin, ArgMax
+  , Arg(..)
+  , ArgMin
+  , ArgMax
+  ) where
+
+import Data.Semigroup
diff --git a/src/Data/Semigroup/Compat/Repl.hs b/src/Data/Semigroup/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Semigroup/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Data.Semigroup.Compat"
+-- from a globally unique namespace.
+module Data.Semigroup.Compat.Repl (
+  module Data.Semigroup.Compat
+) where
+import "this" Data.Semigroup.Compat
diff --git a/src/Data/String/Compat.hs b/src/Data/String/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/String/Compat.hs
@@ -0,0 +1,11 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+module Data.String.Compat (
+  module Base
+, String
+, lines
+, words
+, unlines
+, unwords
+) where
+
+import Data.String as Base
diff --git a/src/Data/String/Compat/Repl.hs b/src/Data/String/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/String/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Data.String.Compat"
+-- from a globally unique namespace.
+module Data.String.Compat.Repl (
+  module Data.String.Compat
+) where
+import "this" Data.String.Compat
diff --git a/src/Data/Traversable/Compat.hs b/src/Data/Traversable/Compat.hs
--- a/src/Data/Traversable/Compat.hs
+++ b/src/Data/Traversable/Compat.hs
@@ -1,23 +1,98 @@
-{-# OPTIONS_GHC -fno-warn-orphans #-}
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
+{-# LANGUAGE Trustworthy #-}
+#if !(MIN_VERSION_base(4,18,0))
+{-# LANGUAGE ScopedTypeVariables #-}
+#endif
 module Data.Traversable.Compat (
   module Base
-, Traversable(..)
+, mapAccumM
+, forAccumM
 ) where
+
 import Data.Traversable as Base
 
-#if !MIN_VERSION_base(4,7,0)
-import Data.Either (Either(..))
-import Data.Foldable.Compat ()
-import Data.Function (($))
-import Control.Applicative (Const(..),pure,(<$>))
+#if !(MIN_VERSION_base(4,18,0))
+import Prelude.Compat
 
-instance Traversable (Either a) where
-    traverse _ (Left x) = pure (Left x)
-    traverse f (Right y) = Right <$> f y
+import Control.Monad.Compat (liftM)
 
-instance Traversable ((,) a) where
-    traverse f (x, y) = (,) x <$> f y
+import Data.Coerce (Coercible, coerce)
+#endif
 
-instance Traversable (Const m) where
-    traverse _ (Const m) = pure $ Const m
+#if !(MIN_VERSION_base(4,18,0))
+-- | A state transformer monad parameterized by the state and inner monad.
+-- The implementation is copied from the transformers package with the
+-- return tuple swapped.
+--
+-- /Since: 4.18.0.0/
+newtype StateT s m a = StateT { runStateT :: s -> m (s, a) }
+
+-- | /Since: 4.18.0.0/
+instance Monad m => Functor (StateT s m) where
+    fmap = liftM
+    {-# INLINE fmap #-}
+
+-- | /Since: 4.18.0.0/
+instance Monad m => Applicative (StateT s m) where
+    pure a = StateT $ \ s -> return (s, a)
+    {-# INLINE pure #-}
+    StateT mf <*> StateT mx = StateT $ \ s -> do
+        (s', f) <- mf s
+        (s'', x) <- mx s'
+        return (s'', f x)
+    {-# INLINE (<*>) #-}
+    m *> k = m >>= \_ -> k
+    {-# INLINE (*>) #-}
+
+(#.) :: Coercible b c => (b -> c) -> (a -> b) -> (a -> c)
+(#.) _f = coerce
+
+-- | /Since: 4.18.0.0/
+instance (Monad m) => Monad (StateT s m) where
+    m >>= k  = StateT $ \ s -> do
+        (s', a) <- runStateT m s
+        runStateT (k a) s'
+    {-# INLINE (>>=) #-}
+# if !(MIN_VERSION_base(4,11,0))
+    return = pure
+# endif
+
+-- | The `mapAccumM` function behaves like a combination of `mapM` and
+-- `mapAccumL` that traverses the structure while evaluating the actions
+-- and passing an accumulating parameter from left to right.
+-- It returns a final value of this accumulator together with the new structure.
+-- The accummulator is often used for caching the intermediate results of a computation.
+--
+--  @since 4.18.0.0
+--
+-- ==== __Examples__
+--
+-- Basic usage:
+--
+-- >>> let expensiveDouble a = putStrLn ("Doubling " <> show a) >> pure (2 * a)
+-- >>> :{
+-- mapAccumM (\cache a -> case lookup a cache of
+--     Nothing -> expensiveDouble a >>= \double -> pure ((a, double):cache, double)
+--     Just double -> pure (cache, double)
+--     ) [] [1, 2, 3, 1, 2, 3]
+-- :}
+-- Doubling 1
+-- Doubling 2
+-- Doubling 3
+-- ([(3,6),(2,4),(1,2)],[2,4,6,2,4,6])
+--
+mapAccumM
+  :: forall m t s a b. (Monad m, Traversable t)
+  => (s -> a -> m (s, b))
+  -> s -> t a -> m (s, t b)
+mapAccumM f s t = runStateT (mapM (StateT #. flip f) t) s
+
+-- | 'forAccumM' is 'mapAccumM' with the arguments rearranged.
+--
+-- @since 4.18.0.0
+forAccumM
+  :: (Monad m, Traversable t)
+  => s -> t a -> (s -> a -> m (s, b)) -> m (s, t b)
+{-# INLINE forAccumM #-}
+forAccumM s t f = mapAccumM f s t
 #endif
diff --git a/src/Data/Traversable/Compat/Repl.hs b/src/Data/Traversable/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Traversable/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Data.Traversable.Compat"
+-- from a globally unique namespace.
+module Data.Traversable.Compat.Repl (
+  module Data.Traversable.Compat
+) where
+import "this" Data.Traversable.Compat
diff --git a/src/Data/Tuple/Compat.hs b/src/Data/Tuple/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Tuple/Compat.hs
@@ -0,0 +1,34 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
+{-# LANGUAGE Safe #-}
+#if MIN_VERSION_ghc_prim(0,7,0)
+{-# LANGUAGE PatternSynonyms #-}
+#endif
+-- | Note that we only re-export @MkSolo@ when building with @ghc-prim-0.10.0@
+-- (bundled with GHC 9.6) or later. If you want to backport @MkSolo@ to older
+-- versions of GHC, import @Data.Tuple.Compat@ from @base-compat-batteries@
+-- instead.
+module Data.Tuple.Compat
+  ( fst
+  , snd
+  , curry
+  , uncurry
+  , swap
+#if MIN_VERSION_ghc_prim(0,10,0)
+  , Solo(MkSolo,Solo)
+#elif MIN_VERSION_ghc_prim(0,7,0)
+  , Solo(Solo)
+#endif
+#if MIN_VERSION_ghc_prim(0,8,0)
+  , getSolo
+#endif
+  ) where
+
+import Data.Tuple
+
+#if !(MIN_VERSION_base(4,16,0)) && MIN_VERSION_ghc_prim(0,7,0)
+import GHC.Tuple (Solo(..))
+#endif
+
+#if MIN_VERSION_ghc_prim(0,8,0) && !(MIN_VERSION_ghc_prim(0,11,0))
+import GHC.Tuple (getSolo)
+#endif
diff --git a/src/Data/Tuple/Compat/Repl.hs b/src/Data/Tuple/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Tuple/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Data.Tuple.Compat"
+-- from a globally unique namespace.
+module Data.Tuple.Compat.Repl (
+  module Data.Tuple.Compat
+) where
+import "this" Data.Tuple.Compat
diff --git a/src/Data/Type/Coercion/Compat.hs b/src/Data/Type/Coercion/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Type/Coercion/Compat.hs
@@ -0,0 +1,19 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE Trustworthy #-}
+module Data.Type.Coercion.Compat (
+  module Base
+, gcoerceWith
+) where
+
+import Data.Type.Coercion as Base
+
+# if !(MIN_VERSION_base(4,10,0))
+import Data.Coerce (Coercible)
+
+-- | Generalized form of type-safe cast using representational equality
+--
+-- /Since: 4.10.0.0/
+gcoerceWith :: Coercion a b -> (Coercible a b => r) -> r
+gcoerceWith Coercion x = x
+# endif
diff --git a/src/Data/Type/Coercion/Compat/Repl.hs b/src/Data/Type/Coercion/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Type/Coercion/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Data.Type.Coercion.Compat"
+-- from a globally unique namespace.
+module Data.Type.Coercion.Compat.Repl (
+  module Data.Type.Coercion.Compat
+) where
+import "this" Data.Type.Coercion.Compat
diff --git a/src/Data/Type/Equality/Compat.hs b/src/Data/Type/Equality/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Type/Equality/Compat.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE Trustworthy #-}
+module Data.Type.Equality.Compat (
+  module Base
+) where
+
+import Data.Type.Equality as Base
diff --git a/src/Data/Type/Equality/Compat/Repl.hs b/src/Data/Type/Equality/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Type/Equality/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Data.Type.Equality.Compat"
+-- from a globally unique namespace.
+module Data.Type.Equality.Compat.Repl (
+  module Data.Type.Equality.Compat
+) where
+import "this" Data.Type.Equality.Compat
diff --git a/src/Data/Typeable/Compat.hs b/src/Data/Typeable/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Typeable/Compat.hs
@@ -0,0 +1,58 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
+{-# LANGUAGE Trustworthy #-}
+#if MIN_VERSION_base(4,10,0) && !(MIN_VERSION_base(4,19,0))
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE TypeOperators #-}
+#endif
+module Data.Typeable.Compat (
+  module Base
+#if MIN_VERSION_base(4,10,0)
+, heqT
+, decT
+, hdecT
+#endif
+) where
+
+import Data.Typeable as Base
+
+#if MIN_VERSION_base(4,10,0) && !(MIN_VERSION_base(4,19,0))
+import Prelude.Compat
+
+import Data.Void (Void)
+import qualified Type.Reflection.Compat as TR
+#endif
+
+#if MIN_VERSION_base(4,10,0)
+# if !(MIN_VERSION_base(4,18,0))
+-- | Extract a witness of heterogeneous equality of two types
+--
+-- /Since: 4.18.0.0/
+heqT :: forall a b. (Typeable a, Typeable b) => Maybe (a :~~: b)
+heqT = ta `TR.eqTypeRep` tb
+  where
+    ta = TR.typeRep :: TR.TypeRep a
+    tb = TR.typeRep :: TR.TypeRep b
+# endif
+
+# if !(MIN_VERSION_base(4,19,0))
+-- | Decide an equality of two types
+--
+-- /Since: 4.19.0.0/
+decT :: forall a b. (Typeable a, Typeable b) => Either (a :~: b -> Void) (a :~: b)
+decT = case hdecT @a @b of
+  Right HRefl -> Right Refl
+  Left p      -> Left (\Refl -> p HRefl)
+
+-- | Decide heterogeneous equality of two types.
+--
+-- /Since: 4.19.0.0/
+hdecT :: forall a b. (Typeable a, Typeable b) => Either (a :~~: b -> Void) (a :~~: b)
+hdecT = ta `TR.decTypeRep` tb
+  where
+    ta = TR.typeRep :: TR.TypeRep a
+    tb = TR.typeRep :: TR.TypeRep b
+# endif
+#endif
diff --git a/src/Data/Typeable/Compat/Repl.hs b/src/Data/Typeable/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Typeable/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Data.Typeable.Compat"
+-- from a globally unique namespace.
+module Data.Typeable.Compat.Repl (
+  module Data.Typeable.Compat
+) where
+import "this" Data.Typeable.Compat
diff --git a/src/Data/Version/Compat.hs b/src/Data/Version/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Version/Compat.hs
@@ -0,0 +1,6 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+module Data.Version.Compat (
+  module Base
+, makeVersion
+) where
+import Data.Version as Base
diff --git a/src/Data/Version/Compat/Repl.hs b/src/Data/Version/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Version/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Data.Version.Compat"
+-- from a globally unique namespace.
+module Data.Version.Compat.Repl (
+  module Data.Version.Compat
+) where
+import "this" Data.Version.Compat
diff --git a/src/Data/Void/Compat.hs b/src/Data/Void/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Void/Compat.hs
@@ -0,0 +1,6 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+module Data.Void.Compat (
+  module Base
+) where
+
+import Data.Void as Base
diff --git a/src/Data/Void/Compat/Repl.hs b/src/Data/Void/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Void/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Data.Void.Compat"
+-- from a globally unique namespace.
+module Data.Void.Compat.Repl (
+  module Data.Void.Compat
+) where
+import "this" Data.Void.Compat
diff --git a/src/Data/Word/Compat.hs b/src/Data/Word/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Word/Compat.hs
@@ -0,0 +1,9 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+module Data.Word.Compat (
+  module Base
+, byteSwap16
+, byteSwap32
+, byteSwap64
+) where
+
+import Data.Word as Base
diff --git a/src/Data/Word/Compat/Repl.hs b/src/Data/Word/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Word/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Data.Word.Compat"
+-- from a globally unique namespace.
+module Data.Word.Compat.Repl (
+  module Data.Word.Compat
+) where
+import "this" Data.Word.Compat
diff --git a/src/Debug/Trace/Compat.hs b/src/Debug/Trace/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Debug/Trace/Compat.hs
@@ -0,0 +1,51 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
+module Debug.Trace.Compat (
+  module Base
+, traceId
+, traceShowId
+, traceM
+, traceShowM
+, traceWith
+, traceShowWith
+, traceEventWith
+) where
+
+import Debug.Trace as Base
+
+#if !(MIN_VERSION_base(4,18,0))
+import Prelude.Compat
+#endif
+
+#if !(MIN_VERSION_base(4,18,0))
+{-|
+Like 'trace', but outputs the result of calling a function on the argument.
+
+>>> traceWith fst ("hello","world")
+hello
+("hello","world")
+
+/Since: 4.18.0.0/
+-}
+traceWith :: (a -> String) -> a -> a
+traceWith f a = trace (f a) a
+
+{-|
+Like 'traceWith', but uses 'show' on the result of the function to convert it to
+a 'String'.
+
+>>> traceShowWith length [1,2,3]
+3
+[1,2,3]
+
+/Since: 4.18.0.0/
+-}
+traceShowWith :: Show b => (a -> b) -> a -> a
+traceShowWith f = traceWith (show . f)
+
+-- | Like 'traceEvent', but emits the result of calling a function on its
+-- argument.
+--
+-- /Since: 4.18.0.0/
+traceEventWith :: (a -> String) -> a -> a
+traceEventWith f a = traceEvent (f a) a
+#endif
diff --git a/src/Debug/Trace/Compat/Repl.hs b/src/Debug/Trace/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Debug/Trace/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Debug.Trace.Compat"
+-- from a globally unique namespace.
+module Debug.Trace.Compat.Repl (
+  module Debug.Trace.Compat
+) where
+import "this" Debug.Trace.Compat
diff --git a/src/Foreign/Compat.hs b/src/Foreign/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/Compat.hs
@@ -0,0 +1,9 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE Trustworthy #-}
+module Foreign.Compat (
+  module Base
+, module Marshal
+) where
+import Foreign as Base
+
+import Foreign.Marshal.Compat as Marshal
diff --git a/src/Foreign/Compat/Repl.hs b/src/Foreign/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Foreign.Compat"
+-- from a globally unique namespace.
+module Foreign.Compat.Repl (
+  module Foreign.Compat
+) where
+import "this" Foreign.Compat
diff --git a/src/Foreign/ForeignPtr/Compat.hs b/src/Foreign/ForeignPtr/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/ForeignPtr/Compat.hs
@@ -0,0 +1,28 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE Trustworthy #-}
+module Foreign.ForeignPtr.Compat (
+  module Base
+, plusForeignPtr
+) where
+
+import Foreign.ForeignPtr as Base
+
+#if !(MIN_VERSION_base(4,10,0))
+import GHC.Exts (Int(..), plusAddr#)
+import GHC.ForeignPtr (ForeignPtr(..))
+
+plusForeignPtr :: ForeignPtr a -> Int -> ForeignPtr b
+-- ^Advances the given address by the given offset in bytes.
+--
+-- The new 'ForeignPtr' shares the finalizer of the original,
+-- equivalent from a finalization standpoint to just creating another
+-- reference to the original. That is, the finalizer will not be
+-- called before the new 'ForeignPtr' is unreachable, nor will it be
+-- called an additional time due to this call, and the finalizer will
+-- be called with the same address that it would have had this call
+-- not happened, *not* the new address.
+--
+-- /Since: 4.10.0.0/
+plusForeignPtr (ForeignPtr addr c) (I# d) = ForeignPtr (plusAddr# addr d) c
+#endif
diff --git a/src/Foreign/ForeignPtr/Compat/Repl.hs b/src/Foreign/ForeignPtr/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/ForeignPtr/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Foreign.ForeignPtr.Compat"
+-- from a globally unique namespace.
+module Foreign.ForeignPtr.Compat.Repl (
+  module Foreign.ForeignPtr.Compat
+) where
+import "this" Foreign.ForeignPtr.Compat
diff --git a/src/Foreign/ForeignPtr/Safe/Compat.hs b/src/Foreign/ForeignPtr/Safe/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/ForeignPtr/Safe/Compat.hs
@@ -0,0 +1,35 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
+{-# LANGUAGE Trustworthy #-}
+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 --git a/src/Foreign/ForeignPtr/Safe/Compat/Repl.hs b/src/Foreign/ForeignPtr/Safe/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/ForeignPtr/Safe/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Foreign.ForeignPtr.Safe.Compat"
+-- from a globally unique namespace.
+module Foreign.ForeignPtr.Safe.Compat.Repl (
+  module Foreign.ForeignPtr.Safe.Compat
+) where
+import "this" Foreign.ForeignPtr.Safe.Compat
diff --git a/src/Foreign/ForeignPtr/Unsafe/Compat.hs b/src/Foreign/ForeignPtr/Unsafe/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/ForeignPtr/Unsafe/Compat.hs
@@ -0,0 +1,7 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+module Foreign.ForeignPtr.Unsafe.Compat (
+  -- ** Unsafe low-level operations
+  unsafeForeignPtrToPtr
+) where
+
+import Foreign.ForeignPtr.Unsafe (unsafeForeignPtrToPtr)
diff --git a/src/Foreign/ForeignPtr/Unsafe/Compat/Repl.hs b/src/Foreign/ForeignPtr/Unsafe/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/ForeignPtr/Unsafe/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Foreign.ForeignPtr.Unsafe.Compat"
+-- from a globally unique namespace.
+module Foreign.ForeignPtr.Unsafe.Compat.Repl (
+  module Foreign.ForeignPtr.Unsafe.Compat
+) where
+import "this" Foreign.ForeignPtr.Unsafe.Compat
diff --git a/src/Foreign/Marshal/Alloc/Compat.hs b/src/Foreign/Marshal/Alloc/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/Marshal/Alloc/Compat.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+module Foreign.Marshal.Alloc.Compat (
+  module Base
+, calloc
+, callocBytes
+) where
+import Foreign.Marshal.Alloc as Base
diff --git a/src/Foreign/Marshal/Alloc/Compat/Repl.hs b/src/Foreign/Marshal/Alloc/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/Marshal/Alloc/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Foreign.Marshal.Alloc.Compat"
+-- from a globally unique namespace.
+module Foreign.Marshal.Alloc.Compat.Repl (
+  module Foreign.Marshal.Alloc.Compat
+) where
+import "this" Foreign.Marshal.Alloc.Compat
diff --git a/src/Foreign/Marshal/Array/Compat.hs b/src/Foreign/Marshal/Array/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/Marshal/Array/Compat.hs
@@ -0,0 +1,7 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+module Foreign.Marshal.Array.Compat (
+  module Base
+, callocArray
+, callocArray0
+) where
+import Foreign.Marshal.Array as Base
diff --git a/src/Foreign/Marshal/Array/Compat/Repl.hs b/src/Foreign/Marshal/Array/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/Marshal/Array/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Foreign.Marshal.Array.Compat"
+-- from a globally unique namespace.
+module Foreign.Marshal.Array.Compat.Repl (
+  module Foreign.Marshal.Array.Compat
+) where
+import "this" Foreign.Marshal.Array.Compat
diff --git a/src/Foreign/Marshal/Compat.hs b/src/Foreign/Marshal/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/Marshal/Compat.hs
@@ -0,0 +1,13 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE Trustworthy #-}
+module Foreign.Marshal.Compat (
+  module Base
+, module Alloc
+, module Array
+, module Utils
+) where
+import Foreign.Marshal as Base
+
+import Foreign.Marshal.Alloc.Compat as Alloc
+import Foreign.Marshal.Array.Compat as Array
+import Foreign.Marshal.Utils.Compat as Utils
diff --git a/src/Foreign/Marshal/Compat/Repl.hs b/src/Foreign/Marshal/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/Marshal/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Foreign.Marshal.Compat"
+-- from a globally unique namespace.
+module Foreign.Marshal.Compat.Repl (
+  module Foreign.Marshal.Compat
+) where
+import "this" Foreign.Marshal.Compat
diff --git a/src/Foreign/Marshal/Safe/Compat.hs b/src/Foreign/Marshal/Safe/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/Marshal/Safe/Compat.hs
@@ -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 --git a/src/Foreign/Marshal/Safe/Compat/Repl.hs b/src/Foreign/Marshal/Safe/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/Marshal/Safe/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Foreign.Marshal.Safe.Compat"
+-- from a globally unique namespace.
+module Foreign.Marshal.Safe.Compat.Repl (
+  module Foreign.Marshal.Safe.Compat
+) where
+import "this" Foreign.Marshal.Safe.Compat
diff --git a/src/Foreign/Marshal/Unsafe/Compat.hs b/src/Foreign/Marshal/Unsafe/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/Marshal/Unsafe/Compat.hs
@@ -0,0 +1,7 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+module Foreign.Marshal.Unsafe.Compat (
+  -- * Unsafe functions
+  unsafeLocalState
+) where
+
+import Foreign.Marshal.Unsafe (unsafeLocalState)
diff --git a/src/Foreign/Marshal/Unsafe/Compat/Repl.hs b/src/Foreign/Marshal/Unsafe/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/Marshal/Unsafe/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Foreign.Marshal.Unsafe.Compat"
+-- from a globally unique namespace.
+module Foreign.Marshal.Unsafe.Compat.Repl (
+  module Foreign.Marshal.Unsafe.Compat
+) where
+import "this" Foreign.Marshal.Unsafe.Compat
diff --git a/src/Foreign/Marshal/Utils/Compat.hs b/src/Foreign/Marshal/Utils/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/Marshal/Utils/Compat.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+module Foreign.Marshal.Utils.Compat (
+  module Base
+, fillBytes
+) where
+
+import Foreign.Marshal.Utils as Base
diff --git a/src/Foreign/Marshal/Utils/Compat/Repl.hs b/src/Foreign/Marshal/Utils/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/Marshal/Utils/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Foreign.Marshal.Utils.Compat"
+-- from a globally unique namespace.
+module Foreign.Marshal.Utils.Compat.Repl (
+  module Foreign.Marshal.Utils.Compat
+) where
+import "this" Foreign.Marshal.Utils.Compat
diff --git a/src/Numeric/Compat.hs b/src/Numeric/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Numeric/Compat.hs
@@ -0,0 +1,79 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
+module Numeric.Compat (
+  module Base
+, showBin
+, showFFloatAlt
+, showGFloatAlt
+, showHFloat
+, readBin
+) where
+
+import Numeric as Base
+
+#if !(MIN_VERSION_base(4,16,0))
+import Data.Char (intToDigit)
+import Prelude
+import Text.ParserCombinators.ReadP (readP_to_S)
+import qualified Text.Read.Lex.Compat as L
+#endif
+
+#if !(MIN_VERSION_base(4,11,0))
+{- | Show a floating-point value in the hexadecimal format,
+similar to the @%a@ specifier in C's printf.
+
+  >>> showHFloat (212.21 :: Double) ""
+  "0x1.a86b851eb851fp7"
+  >>> showHFloat (-12.76 :: Float) ""
+  "-0x1.9851ecp3"
+  >>> showHFloat (-0 :: Double) ""
+  "-0x0p+0"
+-}
+showHFloat :: RealFloat a => a -> ShowS
+showHFloat = showString . fmt
+  where
+  fmt x
+    | isNaN x                   = "NaN"
+    | isInfinite x              = (if x < 0 then "-" else "") ++ "Infinity"
+    | x < 0 || isNegativeZero x = '-' : cvt (-x)
+    | otherwise                 = cvt x
+
+  cvt x
+    | x == 0 = "0x0p+0"
+    | otherwise =
+      case floatToDigits 2 x of
+        r@([], _) -> error $ "Impossible happened: showHFloat: " ++ show r
+        (d:ds, e) -> "0x" ++ show d ++ frac ds ++ "p" ++ show (e-1)
+
+  -- Given binary digits, convert them to hex in blocks of 4
+  -- Special case: If all 0's, just drop it.
+  frac digits
+    | allZ digits = ""
+    | otherwise   = "." ++ hex digits
+    where
+    hex ds =
+      case ds of
+        []                -> ""
+        [a]               -> hexDigit a 0 0 0 ""
+        [a,b]             -> hexDigit a b 0 0 ""
+        [a,b,c]           -> hexDigit a b c 0 ""
+        a : b : c : d : r -> hexDigit a b c d (hex r)
+
+  hexDigit a b c d = showHex (8*a + 4*b + 2*c + d)
+
+  allZ xs = case xs of
+              x : more -> x == 0 && allZ more
+              []       -> True
+#endif
+
+#if !(MIN_VERSION_base(4,16,0))
+-- | Read an unsigned number in binary notation.
+--
+-- >>> readBin "10011"
+-- [(19,"")]
+readBin :: (Eq a, Num a) => ReadS a
+readBin = readP_to_S L.readBinP
+
+-- | Show /non-negative/ 'Integral' numbers in base 2.
+showBin :: (Integral a, Show a) => a -> ShowS
+showBin = showIntAtBase 2  intToDigit
+#endif
diff --git a/src/Numeric/Compat/Repl.hs b/src/Numeric/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Numeric/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Numeric.Compat"
+-- from a globally unique namespace.
+module Numeric.Compat.Repl (
+  module Numeric.Compat
+) where
+import "this" Numeric.Compat
diff --git a/src/Numeric/Natural/Compat.hs b/src/Numeric/Natural/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Numeric/Natural/Compat.hs
@@ -0,0 +1,12 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
+{-# LANGUAGE Trustworthy #-}
+module Numeric.Natural.Compat (
+  module Base
+, minusNaturalMaybe
+) where
+
+import Numeric.Natural as Base
+
+#if !(MIN_VERSION_base(4,18,0))
+import GHC.Natural (minusNaturalMaybe)
+#endif
diff --git a/src/Numeric/Natural/Compat/Repl.hs b/src/Numeric/Natural/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Numeric/Natural/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Numeric.Natural.Compat"
+-- from a globally unique namespace.
+module Numeric.Natural.Compat.Repl (
+  module Numeric.Natural.Compat
+) where
+import "this" Numeric.Natural.Compat
diff --git a/src/Prelude/Compat.hs b/src/Prelude/Compat.hs
--- a/src/Prelude/Compat.hs
+++ b/src/Prelude/Compat.hs
@@ -1,8 +1,316 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
+{-# LANGUAGE Trustworthy #-}
+#if MIN_VERSION_base(4,10,0) && !(MIN_VERSION_base(4,12,0))
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE TypeInType #-}
+#endif
+#if MIN_VERSION_base(4,17,0) && !(MIN_VERSION_base(4,20,0))
+{-# LANGUAGE ExplicitNamespaces #-}
+#endif
 module Prelude.Compat (
+#if MIN_VERSION_base(4,20,0)
   module Base
-) where
-#if MIN_VERSION_base(4,6,0)
-import Prelude as Base
 #else
-import Prelude as Base hiding (catch)
+  either
+, all
+, and
+, any
+, concat
+, concatMap
+, mapM_
+, notElem
+, or
+, sequence_
+, (<$>)
+, maybe
+, lines
+, unlines
+, unwords
+, words
+, curry
+, fst
+, snd
+, uncurry
+, ($!)
+, (++)
+, (.)
+, (=<<)
+, asTypeOf
+, const
+, flip
+, id
+, map
+, otherwise
+, until
+, ioError
+, userError
+, (!!)
+, break
+, cycle
+, drop
+, dropWhile
+, filter
+, head
+, init
+, iterate
+, last
+, lookup
+, repeat
+, replicate
+, reverse
+, scanl
+, scanl1
+, scanr
+, scanr1
+, span
+, splitAt
+, tail
+, take
+, takeWhile
+, unzip
+, unzip3
+, zip
+, zip3
+, zipWith
+, zipWith3
+, subtract
+, lex
+, readParen
+, (^)
+, (^^)
+
+, even
+, fromIntegral
+, gcd
+, lcm
+, odd
+, realToFrac
+, showChar
+, showParen
+, showString
+, shows
+, appendFile
+, getChar
+, getContents
+, getLine
+, interact
+, print
+, putChar
+, putStr
+, putStrLn
+, readFile
+, readIO
+, readLn
+, writeFile
+, read
+, reads
+, (&&)
+, not
+, (||)
+, ($)
+, error
+, errorWithoutStackTrace
+, undefined
+, seq
+
+, elem
+, foldMap
+, foldl
+, foldl'
+, foldl1
+, foldr
+, foldr1
+, length
+, maximum
+, minimum
+, null
+, product
+, sum
+, mapM
+, sequence
+, sequenceA
+, traverse
+, (*>)
+, (<*)
+, (<*>)
+, pure
+, liftA2
+, (<$)
+, fmap
+, (>>)
+, (>>=)
+, fail
+, return
+, mappend
+, mconcat
+, mempty
+, (<>)
+, maxBound
+, minBound
+, enumFrom
+, enumFromThen
+, enumFromThenTo
+, enumFromTo
+, fromEnum
+, pred
+, succ
+, toEnum
+, (**)
+, acos
+, acosh
+, asin
+, asinh
+, atan
+, atanh
+, cos
+, cosh
+, exp
+, log
+, logBase
+, pi
+, sin
+, sinh
+, sqrt
+, tan
+, tanh
+, atan2
+, decodeFloat
+, encodeFloat
+, exponent
+, floatDigits
+, floatRadix
+, floatRange
+, isDenormalized
+, isIEEE
+, isInfinite
+, isNaN
+, isNegativeZero
+, scaleFloat
+, significand
+, (*)
+, (+)
+, (-)
+, abs
+, negate
+, signum
+, readList
+, readsPrec
+, (/)
+, fromRational
+, recip
+, div
+, divMod
+, mod
+, quot
+, quotRem
+, rem
+, toInteger
+, toRational
+, ceiling
+, floor
+, properFraction
+, round
+, truncate
+, show
+, showList
+, showsPrec
+, (/=)
+, (==)
+, (<)
+, (<=)
+, (>)
+, (>=)
+, compare
+, max
+, min
+
+-- classes
+, Applicative
+, Bounded
+, Enum
+, Eq
+, Floating
+, Foldable
+, Fractional
+, Functor
+, Integral
+, Monad
+, MonadFail
+, Monoid
+, Num (fromInteger)
+, Ord
+, Read
+, Real
+, RealFloat
+, RealFrac
+, Semigroup
+, Show
+, Traversable
+
+-- data types
+, IO
+, Char
+, Double
+, Float
+, Int
+, Integer
+, Word
+, Bool (True, False)
+, Either(Left, Right)
+, Maybe(Just, Nothing)
+, Ordering (EQ, GT, LT)
+
+-- type synonyms
+, FilePath
+, IOError
+, Rational
+, ReadS
+, ShowS
+, String
+
+# if MIN_VERSION_base(4,17,0)
+-- The equality types
+, type (~)
+# endif
+#endif
+) where
+
+
+import Prelude as Base hiding (
+#if !(MIN_VERSION_base(4,13,0))
+    fail
+# if MIN_VERSION_base(4,10,0) && !(MIN_VERSION_base(4,12,0))
+  , ($!)
+# endif
+#endif
+  )
+
+#if !(MIN_VERSION_base(4,18,0))
+import Control.Applicative (liftA2)
+#endif
+
+#if !(MIN_VERSION_base(4,20,0))
+import Data.Foldable (foldl')
+#endif
+
+#if !(MIN_VERSION_base(4,11,0))
+import Data.Semigroup as Base (Semigroup((<>)))
+#endif
+
+#if !(MIN_VERSION_base(4,13,0))
+import Control.Monad.Fail as Base (MonadFail(fail))
+#endif
+
+#if MIN_VERSION_base(4,10,0) && !(MIN_VERSION_base(4,12,0))
+import GHC.Exts (TYPE)
+#endif
+
+#if MIN_VERSION_base(4,10,0) && !(MIN_VERSION_base(4,12,0))
+-- | Strict (call-by-value) application operator. It takes a function and an
+-- argument, evaluates the argument to weak head normal form (WHNF), then calls
+-- the function with that value.
+infixr 0 $!
+($!) :: forall r a (b :: TYPE r). (a -> b) -> a -> b
+f $! x = let !vx = x in f vx  -- see #2273
 #endif
diff --git a/src/Prelude/Compat/Repl.hs b/src/Prelude/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Prelude/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Prelude.Compat"
+-- from a globally unique namespace.
+module Prelude.Compat.Repl (
+  module Prelude.Compat
+) where
+import "this" Prelude.Compat
diff --git a/src/System/Environment/Compat.hs b/src/System/Environment/Compat.hs
--- a/src/System/Environment/Compat.hs
+++ b/src/System/Environment/Compat.hs
@@ -1,3 +1,6 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+-- | Miscellaneous information about the system environment.
 module System.Environment.Compat (
   getArgs
 , getProgName
@@ -11,17 +14,3 @@
 ) where
 
 import           System.Environment
-
-#if !MIN_VERSION_base(4,7,0)
-import           System.SetEnv
-#endif
-
-#if !MIN_VERSION_base(4,6,0)
-import Prelude
--- | Return the value of the environment variable @var@, or @Nothing@ if
--- there is no such value.
---
--- For POSIX users, this is equivalent to 'System.Posix.Env.getEnv'.
-lookupEnv :: String -> IO (Maybe String)
-lookupEnv k = lookup k `fmap` getEnvironment
-#endif
diff --git a/src/System/Environment/Compat/Repl.hs b/src/System/Environment/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/System/Environment/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "System.Environment.Compat"
+-- from a globally unique namespace.
+module System.Environment.Compat.Repl (
+  module System.Environment.Compat
+) where
+import "this" System.Environment.Compat
diff --git a/src/System/Exit/Compat.hs b/src/System/Exit/Compat.hs
--- a/src/System/Exit/Compat.hs
+++ b/src/System/Exit/Compat.hs
@@ -1,21 +1,7 @@
-{-# LANGUAGE CPP #-}
+{-# LANGUAGE NoImplicitPrelude #-}
 module System.Exit.Compat (
-  ExitCode(..)
-, exitWith
-, exitFailure
-, exitSuccess
+  module Base
 , die
 ) where
 
-import Prelude
-import System.IO
-
-import System.Exit
-
-#if !MIN_VERSION_base(4,7,1)
--- | Write given error message to `stderr` and terminate with `exitFailure`.
---
--- /Since: 4.7.1.0/
-die :: String -> IO a
-die err = hPutStrLn stderr err >> exitFailure
-#endif
+import System.Exit as Base
diff --git a/src/System/Exit/Compat/Repl.hs b/src/System/Exit/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/System/Exit/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "System.Exit.Compat"
+-- from a globally unique namespace.
+module System.Exit.Compat.Repl (
+  module System.Exit.Compat
+) where
+import "this" System.Exit.Compat
diff --git a/src/System/IO/Compat.hs b/src/System/IO/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/System/IO/Compat.hs
@@ -0,0 +1,46 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
+module System.IO.Compat (
+  module Base
+, getContents'
+, hGetContents'
+, readFile'
+) where
+
+import System.IO as Base
+
+#if !(MIN_VERSION_base(4,15,0))
+import Prelude.Compat
+
+-- | The 'getContents'' operation returns all user input as a single string,
+-- which is fully read before being returned
+-- (same as 'hGetContents'' 'stdin').
+--
+-- /Since: 4.15.0.0/
+
+getContents'    :: IO String
+getContents'    =  hGetContents' stdin
+
+-- | The 'readFile'' function reads a file and
+-- returns the contents of the file as a string.
+-- The file is fully read before being returned, as with 'getContents''.
+--
+-- /Since: 4.15.0.0/
+
+readFile'       :: FilePath -> IO String
+readFile' name  =  openFile name ReadMode >>= hGetContents'
+
+-- | The 'hGetContents'' operation reads all input on the given handle
+-- before returning it as a 'String' and closing the handle.
+--
+-- /Since: 4.15.0.0/
+
+hGetContents'   :: Handle -> IO String
+hGetContents' h =  hGetContents h >>= \s -> length s `seq` return s
+ -- NB: The actual implementation of hGetContents' in `base` uses a lot of
+ -- low-level code from GHC.IO.Handle.Text. What's worse, a lot of this
+ -- low-level code isn't exported, so we'd have to reimplement large chunks
+ -- of it in base-compat if we wanted to backport it. For now, I've opted for
+ -- the simpler approach of simply defining hGetContents' in terms of
+ -- hGetContents, which is the approach that the `extra` and `strict` libraries
+ -- use. (Indeed, the code above is taken from `strict`.)
+#endif
diff --git a/src/System/IO/Compat/Repl.hs b/src/System/IO/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/System/IO/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "System.IO.Compat"
+-- from a globally unique namespace.
+module System.IO.Compat.Repl (
+  module System.IO.Compat
+) where
+import "this" System.IO.Compat
diff --git a/src/System/IO/Error/Compat.hs b/src/System/IO/Error/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/System/IO/Error/Compat.hs
@@ -0,0 +1,37 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
+module System.IO.Error.Compat (
+  module Base
+, isResourceVanishedError
+, resourceVanishedErrorType
+, isResourceVanishedErrorType
+) where
+
+import System.IO.Error as Base
+
+#if !(MIN_VERSION_base(4,14,0))
+import GHC.IO.Exception (IOErrorType(..))
+import Prelude.Compat
+
+-- | An error indicating that the operation failed because the
+-- resource vanished. See 'resourceVanishedErrorType'.
+--
+-- /Since 4.14.0.0/
+isResourceVanishedError :: IOError -> Bool
+isResourceVanishedError = isResourceVanishedErrorType . ioeGetErrorType
+
+-- | I\/O error where the operation failed because the resource vanished.
+-- This happens when, for example, attempting to write to a closed
+-- socket or attempting to write to a named pipe that was deleted.
+--
+-- /Since 4.14.0.0/
+resourceVanishedErrorType :: IOErrorType
+resourceVanishedErrorType = ResourceVanished
+
+-- | I\/O error where the operation failed because the resource vanished.
+-- See 'resourceVanishedErrorType'.
+--
+-- /Since 4.14.0.0/
+isResourceVanishedErrorType :: IOErrorType -> Bool
+isResourceVanishedErrorType ResourceVanished = True
+isResourceVanishedErrorType _ = False
+#endif
diff --git a/src/System/IO/Error/Compat/Repl.hs b/src/System/IO/Error/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/System/IO/Error/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "System.IO.Error.Compat"
+-- from a globally unique namespace.
+module System.IO.Error.Compat.Repl (
+  module System.IO.Error.Compat
+) where
+import "this" System.IO.Error.Compat
diff --git a/src/System/IO/Unsafe/Compat.hs b/src/System/IO/Unsafe/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/System/IO/Unsafe/Compat.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+module System.IO.Unsafe.Compat (
+  module Base
+, unsafeFixIO
+, unsafeDupablePerformIO
+) where
+
+import System.IO.Unsafe as Base
diff --git a/src/System/IO/Unsafe/Compat/Repl.hs b/src/System/IO/Unsafe/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/System/IO/Unsafe/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "System.IO.Unsafe.Compat"
+-- from a globally unique namespace.
+module System.IO.Unsafe.Compat.Repl (
+  module System.IO.Unsafe.Compat
+) where
+import "this" System.IO.Unsafe.Compat
diff --git a/src/Text/Read/Compat.hs b/src/Text/Read/Compat.hs
--- a/src/Text/Read/Compat.hs
+++ b/src/Text/Read/Compat.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE NoImplicitPrelude #-}
 module Text.Read.Compat (
    -- * The 'Read' class
    Read(..),
@@ -24,34 +25,3 @@
 import Text.Read
 import Text.ParserCombinators.ReadPrec
 import qualified Text.Read.Lex as L
-
-#if !MIN_VERSION_base(4,6,0)
-import Prelude
-import qualified Text.ParserCombinators.ReadP as P
-
--- | Parse a string using the 'Read' instance.
--- Succeeds if there is exactly one valid result.
--- A 'Left' value indicates a parse error.
---
--- /Since: 4.6.0.0/
-readEither :: Read a => String -> Either String a
-readEither s =
-  case [ x | (x,"") <- readPrec_to_S read' minPrec s ] of
-    [x] -> Right x
-    []  -> Left "Prelude.read: no parse"
-    _   -> Left "Prelude.read: ambiguous parse"
- where
-  read' =
-    do x <- readPrec
-       lift P.skipSpaces
-       return x
-
--- | Parse a string using the 'Read' instance.
--- Succeeds if there is exactly one valid result.
---
--- /Since: 4.6.0.0/
-readMaybe :: Read a => String -> Maybe a
-readMaybe s = case readEither s of
-                Left _  -> Nothing
-                Right a -> Just a
-#endif
diff --git a/src/Text/Read/Compat/Repl.hs b/src/Text/Read/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Read/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Text.Read.Compat"
+-- from a globally unique namespace.
+module Text.Read.Compat.Repl (
+  module Text.Read.Compat
+) where
+import "this" Text.Read.Compat
diff --git a/src/Text/Read/Lex/Compat.hs b/src/Text/Read/Lex/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Read/Lex/Compat.hs
@@ -0,0 +1,32 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
+{-# LANGUAGE Trustworthy #-}
+module Text.Read.Lex.Compat (
+  module Base
+, readBinP
+) where
+
+import Text.Read.Lex as Base
+
+#if !(MIN_VERSION_base(4,16,0))
+import Data.Char (ord)
+import Prelude
+import Text.ParserCombinators.ReadP (ReadP)
+#endif
+
+#if !(MIN_VERSION_base(4,16,0))
+readBinP :: (Eq a, Num a) => ReadP a
+readBinP = readIntP'2
+{-# SPECIALISE readBinP :: ReadP Integer #-}
+
+readIntP'2 :: (Eq a, Num a) => ReadP a
+readIntP'2 = readIntP 2 isDigit valDigit
+ where
+  isDigit  c = maybe False (const True) (valDig2 c)
+  valDigit c = maybe 0     id           (valDig2 c)
+{-# SPECIALISE readIntP'2 :: ReadP Integer #-}
+
+valDig2 :: Char -> Maybe Int
+valDig2 c
+  | '0' <= c && c <= '1' = Just (ord c - ord '0')
+  | otherwise            = Nothing
+#endif
diff --git a/src/Text/Read/Lex/Compat/Repl.hs b/src/Text/Read/Lex/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Read/Lex/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Text.Read.Lex.Compat"
+-- from a globally unique namespace.
+module Text.Read.Lex.Compat.Repl (
+  module Text.Read.Lex.Compat
+) where
+import "this" Text.Read.Lex.Compat
diff --git a/src/Type/Reflection/Compat.hs b/src/Type/Reflection/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Type/Reflection/Compat.hs
@@ -0,0 +1,106 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
+{-# LANGUAGE Trustworthy #-}
+#if MIN_VERSION_base(4,10,0)
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE ViewPatterns #-}
+# if !(MIN_VERSION_base(4,11,0))
+{-# LANGUAGE TypeInType #-}
+# endif
+#endif
+module Type.Reflection.Compat (
+#if MIN_VERSION_base(4,10,0)
+  module Base
+, withTypeable
+, pattern TypeRep
+, decTypeRep
+#endif
+) where
+
+#if MIN_VERSION_base(4,11,0)
+import Type.Reflection as Base
+#elif MIN_VERSION_base(4,10,0)
+import Type.Reflection as Base hiding (withTypeable)
+#endif
+
+#if MIN_VERSION_base(4,10,0)
+# if !(MIN_VERSION_base(4,11,0))
+import GHC.Exts (TYPE)
+import Type.Reflection (Typeable, TypeRep)
+# endif
+
+# if !(MIN_VERSION_base(4,19,0))
+import Data.Void (Void)
+import Prelude.Compat
+import Type.Reflection.Unsafe (typeRepFingerprint)
+import Unsafe.Coerce (unsafeCoerce)
+# endif
+
+# if !(MIN_VERSION_base(4,11,0))
+-- | Use a 'TypeRep' as 'Typeable' evidence.
+withTypeable :: forall (a :: k) (r :: TYPE rep). ()
+             => TypeRep a -> (Typeable a => r) -> r
+withTypeable rep k = unsafeCoerce k' rep
+  where k' :: Gift a r
+        k' = Gift k
+
+-- | A helper to satisfy the type checker in 'withTypeable'.
+newtype Gift a (r :: TYPE rep) = Gift (Typeable a => r)
+# endif
+
+# if !(MIN_VERSION_base(4,17,0))
+-- | A 'TypeableInstance' wraps up a 'Typeable' instance for explicit
+-- handling. For internal use: for defining 'TypeRep' pattern.
+data TypeableInstance (a :: k) where
+ TypeableInstance :: Typeable a => TypeableInstance a
+
+-- | Get a reified 'Typeable' instance from an explicit 'TypeRep'.
+--
+-- For internal use: for defining 'TypeRep' pattern.
+typeableInstance :: forall a. TypeRep a -> TypeableInstance a
+typeableInstance rep = withTypeable rep TypeableInstance
+
+-- | A explicitly bidirectional pattern synonym to construct a
+-- concrete representation of a type.
+--
+-- As an __expression__: Constructs a singleton @TypeRep a@ given a
+-- implicit 'Typeable a' constraint:
+--
+-- @
+-- TypeRep @a :: Typeable a => TypeRep a
+-- @
+--
+-- As a __pattern__: Matches on an explicit @TypeRep a@ witness bringing
+-- an implicit @Typeable a@ constraint into scope.
+--
+-- @
+-- f :: TypeRep a -> ..
+-- f TypeRep = {- Typeable a in scope -}
+-- @
+--
+-- /Since: 4.17.0.0/
+pattern TypeRep :: forall a. () => Typeable a => TypeRep a
+pattern TypeRep <- (typeableInstance -> TypeableInstance)
+  where TypeRep = typeRep
+# endif
+
+# if !(MIN_VERSION_base(4,19,0))
+-- | Type equality decision
+--
+-- /Since: 4.19.0.0/
+decTypeRep :: forall k1 k2 (a :: k1) (b :: k2).
+             TypeRep a -> TypeRep b -> Either (a :~~: b -> Void) (a :~~: b)
+decTypeRep a b
+  | sameTypeRep a b = Right (unsafeCoerce HRefl)
+  | otherwise       = Left (\HRefl -> errorWithoutStackTrace ("decTypeRep: Impossible equality proof " ++ show a ++ " :~: " ++ show b))
+{-# INLINEABLE decTypeRep #-}
+
+sameTypeRep :: forall k1 k2 (a :: k1) (b :: k2).
+               TypeRep a -> TypeRep b -> Bool
+sameTypeRep a b = typeRepFingerprint a == typeRepFingerprint b
+# endif
+#endif
diff --git a/src/Type/Reflection/Compat/Repl.hs b/src/Type/Reflection/Compat/Repl.hs
new file mode 100644
--- /dev/null
+++ b/src/Type/Reflection/Compat/Repl.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+{-# OPTIONS_GHC -Wno-dodgy-exports -Wno-unused-imports #-}
+-- | Reexports "Type.Reflection.Compat"
+-- from a globally unique namespace.
+module Type.Reflection.Compat.Repl (
+  module Type.Reflection.Compat
+) where
+import "this" Type.Reflection.Compat
diff --git a/test/Spec.hs b/test/Spec.hs
deleted file mode 100644
--- a/test/Spec.hs
+++ /dev/null
@@ -1,1 +0,0 @@
-{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
