diff --git a/base-compat.cabal b/base-compat.cabal
--- a/base-compat.cabal
+++ b/base-compat.cabal
@@ -1,33 +1,33 @@
 name:             base-compat
-version:          0.7.1
+version:          0.8.0
 license:          MIT
 license-file:     LICENSE
 copyright:        (c) 2012-2015 Simon Hengel,
                   (c) 2014 João Cristóvão,
                   (c) 2015 Ryan Scott
-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>
+author:           Simon Hengel <sol@typeful.net>,
+                  João Cristóvão <jmacristovao@gmail.com>,
+                  Ryan Scott <ryan.gl.scott@ku.edu>
+maintainer:       Simon Hengel <sol@typeful.net>,
+                  João Cristóvão <jmacristovao@gmail.com>,
+                  Ryan Scott <ryan.gl.scott@ku.edu>
 build-type:       Simple
 cabal-version:    >= 1.8
 category:         System
 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>
+                  <https://github.com/haskell-compat/base-compat#readme>
 
 source-repository head
   type: git
-  location: https://github.com/sol/base-compat
+  location: https://github.com/haskell-compat/base-compat
 
 library
   ghc-options:
       -Wall
   build-depends:
       base == 4.*
-    , ghc-prim
     , setenv
-  extensions:
-      CPP
-    , NoImplicitPrelude
   ghc-options:
     -fno-warn-duplicate-exports
 
@@ -35,12 +35,8 @@
       src
 
   exposed-modules:
-      Prelude.Compat
-      Control.Applicative.Compat
       Control.Concurrent.MVar.Compat
-      Control.Exception.Compat
       Control.Monad.Compat
-      Data.Bits.Compat
       Data.Bool.Compat
       Data.Either.Compat
       Data.Foldable.Compat
@@ -48,17 +44,13 @@
       Data.Functor.Compat
       Data.List.Compat
       Data.Monoid.Compat
-      Data.Ord.Compat
-      Data.Traversable.Compat
       Data.Version.Compat
       Debug.Trace.Compat
       Foreign.Compat
-      Foreign.Marshal.Compat
       Foreign.Marshal.Alloc.Compat
       Foreign.Marshal.Array.Compat
-      Foreign.Storable.Compat
-      GHC.Generics.Compat
-      System.Console.GetOpt.Compat
+      Foreign.Marshal.Compat
+      Prelude.Compat
       System.Environment.Compat
       System.Exit.Compat
       Text.Read.Compat
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,48 +0,0 @@
-{-# LANGUAGE StandaloneDeriving #-}
-{-# OPTIONS_GHC -fno-warn-orphans #-}
-module Control.Applicative.Compat (
-  module Base
-, Applicative(..)
-, Alternative(..)
-, Const(..)
-, WrappedMonad(..)
-, WrappedArrow(..)
-, ZipList(..)
-) where
-import Control.Applicative as Base
-
-#if !MIN_VERSION_base(4,8,0)
-import Data.Traversable.Compat ()
-import GHC.Generics.Compat ()
-import Prelude.Compat
-#endif
-
-#if !MIN_VERSION_base(4,7,0)
--- 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)
-
-deriving instance Eq a => Eq (ZipList a)
-deriving instance Ord a => Ord (ZipList a)
-deriving instance Read a => Read (ZipList a)
-deriving instance Show a => Show (ZipList a)
-#endif
-
-#if !MIN_VERSION_base(4,8,0)
-deriving instance Eq a => Eq (Const a b)
-deriving instance Ord a => Ord (Const a b)
-
-instance Read a => Read (Const a b) where
-    readsPrec d = readParen (d > 10)
-        $ \r -> [(Const x,t) | ("Const", s) <- lex r, (x, t) <- readsPrec 11 s]
-
-instance Show a => Show (Const a b) where
-    showsPrec d (Const x) = showParen (d > 10) $
-                            showString "Const " . showsPrec 11 x
-#endif
diff --git a/src/Control/Concurrent/MVar/Compat.hs b/src/Control/Concurrent/MVar/Compat.hs
--- a/src/Control/Concurrent/MVar/Compat.hs
+++ b/src/Control/Concurrent/MVar/Compat.hs
@@ -1,10 +1,11 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
 module Control.Concurrent.MVar.Compat (
   module Base
 , withMVarMasked
 ) where
 import Control.Concurrent.MVar as Base
 
-#if !MIN_VERSION_base(4,7,0)
+#if !(MIN_VERSION_base(4,7,0))
 import Control.Exception (mask_, onException)
 import Control.Monad (return)
 import Data.Function (($))
diff --git a/src/Control/Exception/Compat.hs b/src/Control/Exception/Compat.hs
deleted file mode 100644
--- a/src/Control/Exception/Compat.hs
+++ /dev/null
@@ -1,14 +0,0 @@
-{-# LANGUAGE StandaloneDeriving #-}
-{-# OPTIONS_GHC -fno-warn-orphans #-}
-module Control.Exception.Compat (
-  module Base
-, ErrorCall(..)
-) where
-
-import Control.Exception as Base
-
-#if __GLASGOW_HASKELL__ <= 706
-import Prelude.Compat
-deriving instance Ord ErrorCall
-deriving instance Eq ErrorCall
-#endif
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,28 +1,119 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
 module Control.Monad.Compat (
   module Base
 , Monad(..)
 , MonadPlus(..)
-, void
+#if !(MIN_VERSION_base(4,8,0))
+, foldM
+, foldM_
+, forM
+, forM_
+, guard
+, mapM
+, mapM_
+, msum
+, sequence
+, sequence_
+, unless
+, when
+
 , (<$!>)
-) where
-import Control.Monad as Base
+#endif
 
-#if !MIN_VERSION_base(4,3,0)
-import Data.Function (const)
-import Data.Functor (Functor(..))
+#if !(MIN_VERSION_base(4,5,0))
+, void
 #endif
+) where
 
-#if !MIN_VERSION_base(4,8,0)
-import Prelude.Compat (seq)
+#if MIN_VERSION_base(4,8,0)
+import Control.Monad as Base
+#else
+import Control.Monad as Base hiding (
+    foldM
+  , foldM_
+  , forM
+  , forM_
+  , guard
+  , mapM
+  , mapM_
+  , msum
+  , sequence
+  , sequence_
+  , unless
+  , when
+  )
+import Control.Applicative (Alternative(..))
+import Data.Foldable.Compat
+import Data.Traversable
+import Prelude.Compat
 #endif
 
-#if !MIN_VERSION_base(4,3,0)
+#if !(MIN_VERSION_base(4,3,0))
 -- | @'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
 
-#if !MIN_VERSION_base(4,8,0)
+#if !(MIN_VERSION_base(4,8,0))
+-- | Conditional execution of 'Applicative' expressions. For example,
+--
+-- > when debug (putStrLn "Debugging")
+--
+-- will output the string @Debugging@ if the Boolean value @debug@
+-- is 'True', and otherwise do nothing.
+when      :: (Applicative f) => Bool -> f () -> f ()
+{-# INLINEABLE when #-}
+{-# SPECIALISE when :: Bool -> IO () -> IO () #-}
+{-# SPECIALISE when :: Bool -> Maybe () -> Maybe () #-}
+when p s  = if p then s else pure ()
+
+-- | @'guard' b@ is @'pure' ()@ if @b@ is 'True',
+-- and 'empty' if @b@ is 'False'.
+guard           :: (Alternative f) => Bool -> f ()
+guard True      =  pure ()
+guard False     =  empty
+
+-- | The reverse of 'when'.
+unless            :: (Applicative f) => Bool -> f () -> f ()
+{-# INLINEABLE unless #-}
+{-# SPECIALISE unless :: Bool -> IO () -> IO () #-}
+{-# SPECIALISE unless :: Bool -> Maybe () -> Maybe () #-}
+unless p s        =  if p then pure () else s
+
+{- | The 'foldM' function is analogous to 'foldl', except that its result is
+encapsulated in a monad. Note that 'foldM' works from left-to-right over
+the list arguments. This could be an issue where @('>>')@ and the `folded
+function' are not commutative.
+
+
+>       foldM f a1 [x1, x2, ..., xm]
+
+==
+
+>       do
+>         a2 <- f a1 x1
+>         a3 <- f a2 x2
+>         ...
+>         f am xm
+
+If right-to-left evaluation is required, the input list should be reversed.
+
+Note: 'foldM' is the same as 'foldlM'
+-}
+
+foldM          :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m b
+{-# INLINEABLE foldM #-}
+{-# SPECIALISE foldM :: (a -> b -> IO a) -> a -> [b] -> IO a #-}
+{-# SPECIALISE foldM :: (a -> b -> Maybe a) -> a -> [b] -> Maybe a #-}
+foldM          = foldlM
+
+-- | Like 'foldM', but discards the result.
+foldM_         :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m ()
+{-# INLINEABLE foldM_ #-}
+{-# SPECIALISE foldM_ :: (a -> b -> IO a) -> a -> [b] -> IO () #-}
+{-# SPECIALISE foldM_ :: (a -> b -> Maybe a) -> a -> [b] -> Maybe () #-}
+foldM_ f a xs  = foldlM f a xs >> return ()
+
 infixl 4 <$!>
 
 -- | Strict version of 'Data.Functor.<$>'.
diff --git a/src/Data/Bits/Compat.hs b/src/Data/Bits/Compat.hs
deleted file mode 100644
--- a/src/Data/Bits/Compat.hs
+++ /dev/null
@@ -1,39 +0,0 @@
-{-# OPTIONS_GHC -fno-warn-orphans #-}
-module Data.Bits.Compat (
-  module Base
-, Bits(..)
-) where
-import Data.Bits as Base
-
--- These instances are only valid if Bits isn't a subclass of Num (as Bool is
--- not a Num instance), which is only true as of base-4.6.0.0 and later.
-#if MIN_VERSION_base(4,6,0) && !MIN_VERSION_base(4,7,0)
-import Prelude.Compat
-
-instance Bits Bool where
-    (.&.) = (&&)
-
-    (.|.) = (||)
-
-    xor = (/=)
-
-    complement = not
-
-    shift x 0 = x
-    shift _ _ = False
-
-    rotate x _ = x
-
-    bit 0 = True
-    bit _ = False
-
-    testBit x 0 = x
-    testBit _ _ = False
-
-    bitSize _ = 1
-
-    isSigned _ = False
-
-    popCount False = 0
-    popCount True  = 1
-#endif
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,19 +1,12 @@
+{-# LANGUAGE CPP, 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)
-import Data.Bits.Compat ()
+import Data.Bool as Base
 
+#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@.
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,3 +1,4 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
 module Data.Either.Compat (
   module Base
 , isLeft
@@ -5,9 +6,8 @@
 ) where
 import Data.Either as Base
 
-#if !MIN_VERSION_base(4,7,0)
+#if !(MIN_VERSION_base(4,7,0))
 import Data.Bool (Bool(..))
-import Data.Traversable.Compat ()
 
 -- | Return `True` if the given value is a `Left`-value, `False` otherwise.
 --
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,26 @@
-{-# OPTIONS_GHC -fno-warn-orphans #-}
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
 module Data.Foldable.Compat (
   module Base
-, Foldable(..)
+#if !(MIN_VERSION_base(4,8,0))
+, length
+, null
+#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
+import Data.Foldable as Base
 
-instance Foldable ((,) a) where
-    foldMap f (_, y) = f y
+#if !(MIN_VERSION_base(4,8,0))
+import Prelude (Bool(..), Int, (+))
 
-    foldr f z (_, y) = f y z
+-- | Test whether the structure is empty. The default implementation is
+-- optimized for structures that are similar to cons-lists, because there
+-- is no general way to do better.
+null :: Foldable t => t a -> Bool
+null = foldr (\_ _ -> False) True
 
-instance Foldable (Const m) where
-    foldMap _ _ = mempty
+-- | Returns the size/length of a finite structure as an 'Int'.  The
+-- default implementation is optimized for structures that are similar to
+-- cons-lists, because there is no general way to do better.
+length :: Foldable t => t a -> Int
+length = foldl' (\c _ -> c+1) 0
 #endif
diff --git a/src/Data/Function/Compat.hs b/src/Data/Function/Compat.hs
--- a/src/Data/Function/Compat.hs
+++ b/src/Data/Function/Compat.hs
@@ -1,10 +1,11 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
 module Data.Function.Compat (
   module Base
 , (&)
 ) where
 import Data.Function as Base
 
-#if !MIN_VERSION_base(4,8,0)
+#if !(MIN_VERSION_base(4,8,0))
 infixl 1 &
 
 -- | '&' is a reverse application operator.  This provides notational
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,3 +1,4 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
 module Data.Functor.Compat (
   module Base
 , Functor(..)
@@ -6,7 +7,7 @@
 ) where
 import Data.Functor as Base
 
-#if !MIN_VERSION_base(4,7,0)
+#if !(MIN_VERSION_base(4,7,0))
 import Control.Monad.Compat (void)
 import Data.Function (flip)
 
diff --git a/src/Data/List/Compat.hs b/src/Data/List/Compat.hs
--- a/src/Data/List/Compat.hs
+++ b/src/Data/List/Compat.hs
@@ -1,18 +1,80 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
+{-# LANGUAGE BangPatterns #-}
 module Data.List.Compat (
   module Base
-, dropWhileEnd
+#if !(MIN_VERSION_base(4,8,0))
+, all
+, and
+, any
+, concat
+, concatMap
+, elem
+, find
+, foldl
+, foldl'
+, foldl1
+, foldr
+, foldr1
+, length
+, maximum
+, maximumBy
+, minimum
+, minimumBy
+, notElem
+, null
+, or
+, product
+, sum
+, mapAccumL
+, mapAccumR
+
 , isSubsequenceOf
 , sortOn
 , uncons
+, scanl'
+#endif
+
+#if !(MIN_VERSION_base(4,5,0))
+, dropWhileEnd
+#endif
 ) where
-import Data.List as Base
 
-#if !MIN_VERSION_base(4,8,0)
+#if MIN_VERSION_base(4,8,0)
+import Data.List as Base
+#else
+import Data.List as Base hiding (
+    all
+  , and
+  , any
+  , concat
+  , concatMap
+  , elem
+  , find
+  , foldl
+  , foldl'
+  , foldl1
+  , foldr
+  , foldr1
+  , length
+  , maximum
+  , maximumBy
+  , minimum
+  , minimumBy
+  , notElem
+  , null
+  , or
+  , product
+  , sum
+  , mapAccumL
+  , mapAccumR
+  )
+import Data.Foldable.Compat
+import Data.Traversable
 import Prelude.Compat hiding (foldr, null)
 import Data.Ord (comparing)
 #endif
 
-#if !MIN_VERSION_base(4,5,0)
+#if !(MIN_VERSION_base(4,5,0))
 -- | The 'dropWhileEnd' function drops the largest suffix of a list
 -- in which the given predicate holds for all elements.  For example:
 --
@@ -26,7 +88,7 @@
 
 #endif
 
-#if !MIN_VERSION_base(4,8,0)
+#if !(MIN_VERSION_base(4,8,0))
 -- | The 'isSubsequenceOf' function takes two lists and returns 'True' if the
 -- first list is a subsequence of the second list.
 --
@@ -68,4 +130,15 @@
 uncons []               = Nothing
 uncons (x:xs)           = Just (x, xs)
 
+-- | A strictly accumulating version of 'scanl'
+{-# NOINLINE [1] scanl' #-}
+scanl'           :: (b -> a -> b) -> b -> [a] -> [b]
+-- This peculiar form is needed to prevent scanl' from being rewritten
+-- in its own right hand side.
+scanl' = scanlGo'
+  where
+    scanlGo'           :: (b -> a -> b) -> b -> [a] -> [b]
+    scanlGo' f !q ls    = q : (case ls of
+                            []   -> []
+                            x:xs -> scanlGo' f (f q x) xs)
 #endif
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,50 +1,13 @@
-{-# LANGUAGE GeneralizedNewtypeDeriving, StandaloneDeriving #-}
-
-#if __GLASGOW_HASKELL__ >= 702
-{-# LANGUAGE DeriveGeneric #-}
-#endif
-
-#if __GLASGOW_HASKELL__ >= 706
-{-# LANGUAGE PolyKinds #-}
-#endif
-
-{-# OPTIONS_GHC -fno-warn-orphans #-}
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
 module Data.Monoid.Compat (
-        -- * Monoid typeclass
-        Monoid(..),
-        (<>),
-        Dual(..),
-        Endo(..),
-        -- * Bool wrappers
-        All(..),
-        Any(..),
-        -- * Num wrappers
-        Sum(..),
-        Product(..),
-        -- * Maybe wrappers
-        -- $MaybeExamples
-        First(..),
-        Last(..),
-        -- * Alternative wrapper
-        Alt(..)
-  ) where
+  module Base
+, (<>)
+) where
 
 import Data.Monoid as Base
 
--- To import orphan Generic instances for Sum and Product
-import GHC.Generics.Compat ()
-
-#if !MIN_VERSION_base(4,8,0)
-import Control.Applicative
-import Control.Monad
-import Prelude.Compat
-
-# if __GLASGOW_HASKELL__ >= 702
-import GHC.Generics
-# endif
-#endif
+#if !(MIN_VERSION_base(4,5,0))
 
-#if !MIN_VERSION_base(4,5,0)
 infixr 6 <>
 
 -- | An infix synonym for 'mappend'.
@@ -53,36 +16,5 @@
 (<>) :: Monoid m => m -> m -> m
 (<>) = mappend
 {-# INLINE (<>) #-}
-#endif
 
-#if !MIN_VERSION_base(4,7,0)
-deriving instance Num a => Num (Sum a)
-deriving instance Num a => Num (Product a)
-#endif
-
-#if !MIN_VERSION_base(4,8,0)
--- | Monoid under '<|>'.
---
--- /Since: 4.8.0.0/
-newtype Alt f a = Alt {getAlt :: f a}
-  deriving ( Read, Show, Eq, Ord, Num, Enum
-# if __GLASGOW_HASKELL__ >= 702
-           , Generic
-# endif
-# if __GLASGOW_HASKELL__ >= 708
-           , Generic1
-# endif
-           )
-
--- To work around a GHC 7.6 bug, we'll use StandaloneDeriving for generalized
--- derivations that involve higher-kinded typeclasses.
-deriving instance Functor f => Functor (Alt f)
-deriving instance Applicative f => Applicative (Alt f)
-deriving instance Monad m => Monad (Alt m)
-deriving instance Alternative f => Alternative (Alt f)
-deriving instance MonadPlus m => MonadPlus (Alt m)
-
-instance Alternative f => Monoid (Alt f a) where
-    mempty = Alt empty
-    mappend (Alt x) (Alt y) = Alt (x <|> y)
 #endif
diff --git a/src/Data/Ord/Compat.hs b/src/Data/Ord/Compat.hs
deleted file mode 100644
--- a/src/Data/Ord/Compat.hs
+++ /dev/null
@@ -1,22 +0,0 @@
-{-# LANGUAGE StandaloneDeriving #-}
-{-# OPTIONS_GHC -fno-warn-orphans #-}
-module Data.Ord.Compat (
-  module Base
-, Ord(..)
-, Down(..)
-) where
-import Data.Ord as Base
-
-#if !MIN_VERSION_base(4,7,0)
-import Prelude.Compat
-#endif
-
-#if MIN_VERSION_base(4,6,0) && !MIN_VERSION_base(4,7,0)
-deriving instance Read a => Read (Down a)
-deriving instance Show a => Show (Down a)
-#elif !MIN_VERSION_base(4,6,0)
-newtype Down a = Down a deriving (Eq, Show, Read)
-
-instance Ord a => Ord (Down a) where
-    compare (Down x) (Down y) = y `compare` x
-#endif
diff --git a/src/Data/Traversable/Compat.hs b/src/Data/Traversable/Compat.hs
deleted file mode 100644
--- a/src/Data/Traversable/Compat.hs
+++ /dev/null
@@ -1,23 +0,0 @@
-{-# OPTIONS_GHC -fno-warn-orphans #-}
-module Data.Traversable.Compat (
-  module Base
-, Traversable(..)
-) 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,(<$>))
-
-instance Traversable (Either a) where
-    traverse _ (Left x) = pure (Left x)
-    traverse f (Right y) = Right <$> f y
-
-instance Traversable ((,) a) where
-    traverse f (x, y) = (,) x <$> f y
-
-instance Traversable (Const m) where
-    traverse _ (Const m) = pure $ Const m
-#endif
diff --git a/src/Data/Version/Compat.hs b/src/Data/Version/Compat.hs
--- a/src/Data/Version/Compat.hs
+++ b/src/Data/Version/Compat.hs
@@ -1,41 +1,16 @@
-{-# LANGUAGE DeriveDataTypeable, StandaloneDeriving, TypeFamilies #-}
-{-# OPTIONS_GHC -fno-warn-orphans #-}
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
 module Data.Version.Compat (
   module Base
-, Version(..)
 , makeVersion
 ) where
 import Data.Version as Base
 
-#if !MIN_VERSION_base(4,7,0)
-import Data.Data
-#endif
-
-#if !MIN_VERSION_base(4,8,0)
+#if !(MIN_VERSION_base(4,8,0))
 import Prelude.Compat
 
-# if MIN_VERSION_base(4,7,0)
-import GHC.Exts (IsList(..))
-# endif
-#endif
-
-#if !MIN_VERSION_base(4,7,0)
-deriving instance Data Version
-#endif
-
-#if !MIN_VERSION_base(4,8,0)
 -- | Construct tag-less 'Version'
 --
 -- /Since: 4.8.0.0/
 makeVersion :: [Int] -> Version
 makeVersion b = Version b []
-
-# if MIN_VERSION_base(4,7,0)
--- | /Since: 4.8.0.0/
-instance IsList Version where
-  type (Item Version) = Int
-  fromList = makeVersion
-  toList = versionBranch
-# endif
-
 #endif
diff --git a/src/Debug/Trace/Compat.hs b/src/Debug/Trace/Compat.hs
--- a/src/Debug/Trace/Compat.hs
+++ b/src/Debug/Trace/Compat.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
 module Debug.Trace.Compat (
   module Base
 , traceId
@@ -7,7 +8,7 @@
 ) where
 import Debug.Trace as Base
 
-#if !MIN_VERSION_base(4,7,0)
+#if !(MIN_VERSION_base(4,7,0))
 import Prelude.Compat
 
 {-|
diff --git a/src/Foreign/Compat.hs b/src/Foreign/Compat.hs
--- a/src/Foreign/Compat.hs
+++ b/src/Foreign/Compat.hs
@@ -1,11 +1,8 @@
+{-# LANGUAGE NoImplicitPrelude #-}
 module Foreign.Compat (
   module Base
-, module Bits
-, module Storable
 , module Marshal
 ) where
 import Foreign as Base
 
-import Data.Bits.Compat as Bits
 import Foreign.Marshal.Compat as Marshal
-import Foreign.Storable.Compat as Storable
diff --git a/src/Foreign/Marshal/Alloc/Compat.hs b/src/Foreign/Marshal/Alloc/Compat.hs
--- a/src/Foreign/Marshal/Alloc/Compat.hs
+++ b/src/Foreign/Marshal/Alloc/Compat.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
 {-# LANGUAGE ForeignFunctionInterface #-}
 module Foreign.Marshal.Alloc.Compat (
   module Base
@@ -6,10 +7,10 @@
 ) where
 import Foreign.Marshal.Alloc as Base
 
-#if !MIN_VERSION_base(4,8,0)
+#if !(MIN_VERSION_base(4,8,0))
 import Foreign.C.Types
 import Foreign.Ptr (Ptr, nullPtr)
-import Foreign.Storable.Compat (Storable(..))
+import Foreign.Storable (Storable(..))
 import GHC.IO.Exception
 import Prelude.Compat
 
diff --git a/src/Foreign/Marshal/Array/Compat.hs b/src/Foreign/Marshal/Array/Compat.hs
--- a/src/Foreign/Marshal/Array/Compat.hs
+++ b/src/Foreign/Marshal/Array/Compat.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
 module Foreign.Marshal.Array.Compat (
   module Base
 , callocArray
@@ -5,10 +6,10 @@
 ) where
 import Foreign.Marshal.Array as Base
 
-#if !MIN_VERSION_base(4,8,0)
+#if !(MIN_VERSION_base(4,8,0))
 import Foreign.Marshal.Alloc.Compat
 import Foreign.Ptr (Ptr)
-import Foreign.Storable.Compat (Storable(..))
+import Foreign.Storable (Storable(..))
 import Prelude.Compat
 
 -- |Like 'mallocArray', but allocated memory is filled with bytes of value zero.
diff --git a/src/Foreign/Marshal/Compat.hs b/src/Foreign/Marshal/Compat.hs
--- a/src/Foreign/Marshal/Compat.hs
+++ b/src/Foreign/Marshal/Compat.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
 module Foreign.Marshal.Compat (
   module Base
 , module Alloc
diff --git a/src/Foreign/Storable/Compat.hs b/src/Foreign/Storable/Compat.hs
deleted file mode 100644
--- a/src/Foreign/Storable/Compat.hs
+++ /dev/null
@@ -1,42 +0,0 @@
-{-# OPTIONS_GHC -fno-warn-orphans #-}
-module Foreign.Storable.Compat (
-  module Base
-, Storable(..)
-) where
-import Foreign.Storable as Base
-
-#if !MIN_VERSION_base(4,8,0)
-import Data.Complex (Complex(..), realPart)
-import Foreign.Ptr (castPtr)
-import GHC.Real (Ratio(..), (%))
-import Prelude.Compat
-
--- The actual constraint in base-4.8.0.0 doesn't include RealFloat a, but it
--- is needed in previous versions of base due to Complex having lots of
--- RealFloat constraints in its functions' type signatures.
-instance (Storable a, RealFloat a) => Storable (Complex a) where
-    sizeOf a       = 2 * sizeOf (realPart a)
-    alignment a    = alignment (realPart a)
-    peek p           = do
-                        q <- return $ castPtr p
-                        r <- peek q
-                        i <- peekElemOff q 1
-                        return (r :+ i)
-    poke p (r :+ i)  = do
-                        q <-return $  (castPtr p)
-                        poke q r
-                        pokeElemOff q 1 i
-
-instance (Storable a, Integral a) => Storable (Ratio a) where
-    sizeOf (n :% _)    = 2 * sizeOf n
-    alignment (n :% _) = alignment n
-    peek p           = do
-                        q <- return $ castPtr p
-                        r <- peek q
-                        i <- peekElemOff q 1
-                        return (r % i)
-    poke p (r :% i)  = do
-                        q <-return $  (castPtr p)
-                        poke q r
-                        pokeElemOff q 1 i
-#endif
diff --git a/src/GHC/Generics/Compat.hs b/src/GHC/Generics/Compat.hs
deleted file mode 100644
--- a/src/GHC/Generics/Compat.hs
+++ /dev/null
@@ -1,131 +0,0 @@
-{-# LANGUAGE FlexibleContexts, StandaloneDeriving, TypeOperators #-}
-
-#if __GLASGOW_HASKELL__ >= 702
-{-# LANGUAGE DeriveGeneric #-}
-#endif
-{-# OPTIONS_GHC -fno-warn-orphans #-}
-module GHC.Generics.Compat (
--- GHC.Generics is only available on GHC 7.2 and later, so we can't export anything
--- if we're using a GHC prior to 7.2
-#if __GLASGOW_HASKELL__ < 702
-) where
-#else
-  module Base
-  -- * Generic representation types
-, U1(..)
-, Par1(..)
-, Rec1(..)
-, K1(..)
-, M1(..)
-, (:+:)(..)
-, (:*:)(..)
-, (:.:)(..)
-  -- * Generic type classes
-, Generic(..)
-, Generic1(..)
-) where
-import           GHC.Generics as Base
-
-# if !MIN_VERSION_base(4,7,0)
-import           GHC.Read
-import           Prelude.Compat
-import qualified Text.ParserCombinators.ReadPrec as ReadPrec
-import           Text.Read.Lex
-
--- Although DeriveGeneric has been around since GHC 7.2, various bugs cause
--- the standalone-derived code below to fail to compile unless a fairly
--- recent version of GHC is used.
-#  if __GLASGOW_HASKELL__ >= 706
-import           Control.Applicative
-import           Data.Monoid
-
-deriving instance Generic All
-deriving instance Generic Any
-deriving instance Generic (Const a b)
-deriving instance Generic (Dual a)
-deriving instance Generic (Endo a)
-deriving instance Generic (First a)
-deriving instance Generic (Last a)
-deriving instance Generic (Product a)
-deriving instance Generic (Sum a)
-deriving instance Generic (WrappedArrow a b c)
-deriving instance Generic (WrappedMonad m a)
-deriving instance Generic (ZipList a)
-
-deriving instance Generic1 (Const a)
-deriving instance Generic1 Dual
-deriving instance Generic1 First
-deriving instance Generic1 Last
-deriving instance Generic1 Product
-deriving instance Generic1 Sum
-deriving instance Generic1 (WrappedArrow a b)
-deriving instance Generic1 (WrappedMonad m)
-deriving instance Generic1 ZipList
-
-deriving instance Generic (U1 p)
-deriving instance Generic (Par1 p)
-deriving instance Generic (Rec1 f p)
-deriving instance Generic (K1 i c p)
-deriving instance Generic (M1 i c f p)
-deriving instance Generic ((f :+: g) p)
-deriving instance Generic ((f :*: g) p)
-deriving instance Generic ((f :.: g) p)
-#  endif
-
-deriving instance Eq (U1 p)
-deriving instance Ord (U1 p)
-deriving instance Read (U1 p)
-deriving instance Show (U1 p)
-
-deriving instance Eq p => Eq (Par1 p)
-deriving instance Ord p => Ord (Par1 p)
-deriving instance Read p => Read (Par1 p)
-deriving instance Show p => Show (Par1 p)
-
-deriving instance Eq (f p) => Eq (Rec1 f p)
-deriving instance Ord (f p) => Ord (Rec1 f p)
-deriving instance Read (f p) => Read (Rec1 f p)
-deriving instance Show (f p) => Show (Rec1 f p)
-
-deriving instance Eq c => Eq (K1 i c p)
-deriving instance Ord c => Ord (K1 i c p)
-deriving instance Read c => Read (K1 i c p)
-deriving instance Show c => Show (K1 i c p)
-
-deriving instance Eq (f p) => Eq (M1 i c f p)
-deriving instance Ord (f p) => Ord (M1 i c f p)
-deriving instance Read (f p) => Read (M1 i c f p)
-deriving instance Show (f p) => Show (M1 i c f p)
-
-deriving instance (Eq (f p), Eq (g p)) => Eq ((f :+: g) p)
-deriving instance (Ord (f p), Ord (g p)) => Ord ((f :+: g) p)
-deriving instance (Read (f p), Read (g p)) => Read ((f :+: g) p)
-deriving instance (Show (f p), Show (g p)) => Show ((f :+: g) p)
-
-deriving instance (Eq (f p), Eq (g p)) => Eq ((f :*: g) p)
-deriving instance (Ord (f p), Ord (g p)) => Ord ((f :*: g) p)
--- Due to a GHC bug (https://ghc.haskell.org/trac/ghc/ticket/9830), the derived
--- Read and Show instances for infix data constructors will use the wrong
--- precedence (prior to GHC 7.10).
--- We'll manually derive Read :*: and Show :*: instances to avoid this.
-instance (Read (f p), Read (g p)) => Read ((f :*: g) p) where
-    readPrec = parens . ReadPrec.prec 6 $ do
-        fp <- ReadPrec.step readPrec
-        Symbol ":*:" <- lexP
-        gp <- ReadPrec.step readPrec
-        return $ fp :*: gp
-    readListPrec = readListPrecDefault
-instance (Show (f p), Show (g p)) => Show ((f :*: g) p) where
-     showsPrec p (l :*: r) = showParen (p > sixPrec) $
-            showsPrec (sixPrec + 1) l
-         . showString " :*: "
-         . showsPrec (sixPrec + 1) r
-       where sixPrec = 6
-
-deriving instance Eq (f (g p)) => Eq ((f :.: g) p)
-deriving instance Ord (f (g p)) => Ord ((f :.: g) p)
-deriving instance Read (f (g p)) => Read ((f :.: g) p)
-deriving instance Show (f (g p)) => Show ((f :.: g) p)
-# endif
-
-#endif
diff --git a/src/Prelude/Compat.hs b/src/Prelude/Compat.hs
--- a/src/Prelude/Compat.hs
+++ b/src/Prelude/Compat.hs
@@ -1,17 +1,18 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
 module Prelude.Compat (
 #if MIN_VERSION_base(4,8,0)
   module Base
 #else
   either
-, Data.Foldable.all
-, Data.Foldable.and
-, Data.Foldable.any
-, Data.Foldable.concat
-, Data.Foldable.concatMap
-, Data.Foldable.mapM_
-, Data.Foldable.notElem
-, Data.Foldable.or
-, Data.Foldable.sequence_
+, all
+, and
+, any
+, concat
+, concatMap
+, mapM_
+, notElem
+, or
+, sequence_
 , (<$>)
 , maybe
 , lines
@@ -103,18 +104,18 @@
 , undefined
 , seq
 
-, Data.Foldable.elem
+, elem
 , foldMap
-, Data.Foldable.foldl
-, Data.Foldable.foldl1
+, foldl
+, foldl1
 , foldr
-, Data.Foldable.foldr1
+, foldr1
 , length
-, Data.Foldable.maximum
-, Data.Foldable.minimum
+, maximum
+, minimum
 , null
-, Data.Foldable.product
-, Data.Foldable.sum
+, product
+, sum
 , mapM
 , sequence
 , sequenceA
@@ -262,23 +263,36 @@
 
 #else
 
-import Prelude hiding (length, null, foldr, mapM, sequence)
+import Prelude hiding (
+    length
+  , null
+  , foldr
+  , mapM
+  , sequence
+  , all
+  , and
+  , any
+  , concat
+  , concatMap
+  , mapM
+  , mapM_
+  , notElem
+  , or
+  , sequence
+  , sequence_
+  , elem
+  , foldl
+  , foldl1
+  , foldr1
+  , maximum
+  , minimum
+  , product
+  , sum
+  )
 
 import Data.Word
-import Data.Foldable
-import Data.Traversable.Compat
+import Data.Foldable.Compat
+import Data.Traversable
 import Data.Monoid
 import Control.Applicative
-
--- | Test whether the structure is empty. The default implementation is
--- optimized for structures that are similar to cons-lists, because there
--- is no general way to do better.
-null :: Foldable t => t a -> Bool
-null = foldr (\_ _ -> False) True
-
--- | Returns the size/length of a finite structure as an 'Int'.  The
--- default implementation is optimized for structures that are similar to
--- cons-lists, because there is no general way to do better.
-length :: Foldable t => t a -> Int
-length = foldl' (\c _ -> c+1) 0
 #endif
diff --git a/src/System/Console/GetOpt/Compat.hs b/src/System/Console/GetOpt/Compat.hs
deleted file mode 100644
--- a/src/System/Console/GetOpt/Compat.hs
+++ /dev/null
@@ -1,26 +0,0 @@
-{-# OPTIONS_GHC -fno-warn-orphans #-}
-module System.Console.GetOpt.Compat (
-  module Base
-, ArgOrder(..)
-, OptDescr(..)
-, ArgDescr(..)
-) where
-import System.Console.GetOpt as Base
-
-#if !MIN_VERSION_base(4,7,0)
-import Data.Function ((.))
-import Data.Functor (Functor(..))
-
-instance Functor ArgOrder where
-    fmap _ RequireOrder      = RequireOrder
-    fmap _ Permute           = Permute
-    fmap f (ReturnInOrder g) = ReturnInOrder (f . g)
-
-instance Functor OptDescr where
-    fmap f (Option a b argDescr c) = Option a b (fmap f argDescr) c
-
-instance Functor ArgDescr where
-    fmap f (NoArg a)    = NoArg (f a)
-    fmap f (ReqArg g s) = ReqArg (f . g) s
-    fmap f (OptArg g s) = OptArg (f . g) s
-#endif
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,4 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
 -- | Miscellaneous information about the system environment.
 module System.Environment.Compat (
   getArgs
@@ -13,11 +14,11 @@
 
 import           System.Environment
 
-#if !MIN_VERSION_base(4,7,0)
+#if !(MIN_VERSION_base(4,7,0))
 import           System.SetEnv
 #endif
 
-#if !MIN_VERSION_base(4,6,0)
+#if !(MIN_VERSION_base(4,6,0))
 import Prelude.Compat
 -- | Return the value of the environment variable @var@, or @Nothing@ if
 -- there is no such value.
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,15 +1,13 @@
+{-# LANGUAGE CPP, NoImplicitPrelude #-}
 {-# LANGUAGE CPP #-}
 module System.Exit.Compat (
-  ExitCode(..)
-, exitWith
-, exitFailure
-, exitSuccess
+  module Base
 , die
 ) where
 
-import System.Exit
+import System.Exit as Base
 
-#if !MIN_VERSION_base(4,8,0)
+#if !(MIN_VERSION_base(4,8,0))
 
 import Prelude.Compat
 import System.IO
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 CPP, NoImplicitPrelude #-}
 module Text.Read.Compat (
    -- * The 'Read' class
    Read(..),
@@ -25,7 +26,7 @@
 import Text.ParserCombinators.ReadPrec
 import qualified Text.Read.Lex as L
 
-#if !MIN_VERSION_base(4,6,0)
+#if !(MIN_VERSION_base(4,6,0))
 import Prelude.Compat
 import qualified Text.ParserCombinators.ReadP as P
 
