diff --git a/Control/Applicative/Backwards.hs b/Control/Applicative/Backwards.hs
--- a/Control/Applicative/Backwards.hs
+++ b/Control/Applicative/Backwards.hs
@@ -1,11 +1,12 @@
 {-# LANGUAGE CPP #-}
 #if __GLASGOW_HASKELL__ >= 702
 {-# LANGUAGE Safe #-}
+{-# LANGUAGE DeriveGeneric #-}
 #endif
 #if __GLASGOW_HASKELL__ >= 706
 {-# LANGUAGE PolyKinds #-}
 #endif
-#if __GLASGOW_HASKELL__ >= 710
+#if __GLASGOW_HASKELL__ >= 710 && __GLASGOW_HASKELL__ < 802
 {-# LANGUAGE AutoDeriveTypeable #-}
 #endif
 -----------------------------------------------------------------------------
@@ -26,16 +27,32 @@
     Backwards(..),
   ) where
 
+#if MIN_VERSION_base(4,18,0)
+import Data.Foldable1 (Foldable1(foldMap1))
+#endif
 import Data.Functor.Classes
+#if MIN_VERSION_base(4,12,0)
+import Data.Functor.Contravariant
+#endif
+#if __GLASGOW_HASKELL__ >= 704
+import GHC.Generics
+#endif
 
-import Prelude hiding (foldr, foldr1, foldl, foldl1)
+import Prelude hiding (foldr, foldr1, foldl, foldl1, null, length)
 import Control.Applicative
 import Data.Foldable
-import Data.Traversable
+#if !(MIN_VERSION_base(4,8,0)) || defined(__MHS__)
+import Data.Traversable (Traversable(traverse, sequenceA))
+#endif
 
 -- | The same functor, but with an 'Applicative' instance that performs
 -- actions in the reverse order.
 newtype Backwards f a = Backwards { forwards :: f a }
+#if __GLASGOW_HASKELL__ >= 710
+    deriving (Generic, Generic1)
+#elif __GLASGOW_HASKELL__ >= 704
+    deriving (Generic)
+#endif
 
 instance (Eq1 f) => Eq1 (Backwards f) where
     liftEq eq (Backwards x) (Backwards y) = liftEq eq x y
@@ -62,6 +79,8 @@
 instance (Functor f) => Functor (Backwards f) where
     fmap f (Backwards a) = Backwards (fmap f a)
     {-# INLINE fmap #-}
+    x <$ Backwards a = Backwards (x <$ a)
+    {-# INLINE (<$) #-}
 
 -- | Apply @f@-actions in the reverse order.
 instance (Applicative f) => Applicative (Backwards f) where
@@ -69,6 +88,16 @@
     {-# INLINE pure #-}
     Backwards f <*> Backwards a = Backwards (a <**> f)
     {-# INLINE (<*>) #-}
+#if MIN_VERSION_base(4,10,0)
+    liftA2 f (Backwards m) (Backwards n) = Backwards $ liftA2 (flip f) n m
+    {-# INLINE liftA2 #-}
+#endif
+#if MIN_VERSION_base(4,2,0)
+    Backwards xs *> Backwards ys = Backwards (ys <* xs)
+    {-# INLINE (*>) #-}
+    Backwards ys <* Backwards xs = Backwards (xs *> ys)
+    {-# INLINE (<*) #-}
+#endif
 
 -- | Try alternatives in the same order as @f@.
 instance (Alternative f) => Alternative (Backwards f) where
@@ -89,10 +118,28 @@
     {-# INLINE foldr1 #-}
     foldl1 f (Backwards t) = foldl1 f t
     {-# INLINE foldl1 #-}
+#if MIN_VERSION_base(4,8,0)
+    null (Backwards t) = null t
+    length (Backwards t) = length t
+#endif
 
+#if MIN_VERSION_base(4,18,0)
 -- | Derived instance.
+instance (Foldable1 f) => Foldable1 (Backwards f) where
+    foldMap1 f (Backwards t) = foldMap1 f t
+    {-# INLINE foldMap1 #-}
+#endif
+
+-- | Derived instance.
 instance (Traversable f) => Traversable (Backwards f) where
     traverse f (Backwards t) = fmap Backwards (traverse f t)
     {-# INLINE traverse #-}
     sequenceA (Backwards t) = fmap Backwards (sequenceA t)
     {-# INLINE sequenceA #-}
+
+#if MIN_VERSION_base(4,12,0)
+-- | Derived instance.
+instance (Contravariant f) => Contravariant (Backwards f) where
+    contramap f = Backwards . contramap f . forwards
+    {-# INLINE contramap #-}
+#endif
diff --git a/Control/Applicative/Lift.hs b/Control/Applicative/Lift.hs
--- a/Control/Applicative/Lift.hs
+++ b/Control/Applicative/Lift.hs
@@ -1,8 +1,9 @@
 {-# LANGUAGE CPP #-}
 #if __GLASGOW_HASKELL__ >= 702
 {-# LANGUAGE Safe #-}
+{-# LANGUAGE DeriveGeneric #-}
 #endif
-#if __GLASGOW_HASKELL__ >= 710
+#if __GLASGOW_HASKELL__ >= 710 && __GLASGOW_HASKELL__ < 802
 {-# LANGUAGE AutoDeriveTypeable #-}
 #endif
 -----------------------------------------------------------------------------
@@ -23,23 +24,38 @@
     Lift(..),
     unLift,
     mapLift,
+    elimLift,
     -- * Collecting errors
     Errors,
     runErrors,
-    failure
+    failure,
+    eitherToErrors
   ) where
 
+#if MIN_VERSION_base(4,18,0)
+import Data.Foldable1 (Foldable1(foldMap1))
+#endif
 import Data.Functor.Classes
 
 import Control.Applicative
-import Data.Foldable (Foldable(foldMap))
 import Data.Functor.Constant
+#if !(MIN_VERSION_base(4,8,0)) || defined(__MHS__)
+import Data.Foldable (Foldable(foldMap))
 import Data.Monoid (Monoid(..))
 import Data.Traversable (Traversable(traverse))
+#endif
+#if __GLASGOW_HASKELL__ >= 704
+import GHC.Generics
+#endif
 
 -- | Applicative functor formed by adding pure computations to a given
 -- applicative functor.
 data Lift f a = Pure a | Other (f a)
+#if __GLASGOW_HASKELL__ >= 710
+    deriving (Generic, Generic1)
+#elif __GLASGOW_HASKELL__ >= 704
+    deriving (Generic)
+#endif
 
 instance (Eq1 f) => Eq1 (Lift f) where
     liftEq eq (Pure x1) (Pure x2) = eq x1 x2
@@ -89,10 +105,8 @@
 instance (Applicative f) => Applicative (Lift f) where
     pure = Pure
     {-# INLINE pure #-}
-    Pure f <*> Pure x = Pure (f x)
-    Pure f <*> Other y = Other (f <$> y)
-    Other f <*> Pure x = Other (($ x) <$> f)
-    Other f <*> Other y = Other (f <*> y)
+    Pure f <*> ax = f <$> ax
+    Other f <*> ax = Other (f <*> unLift ax)
     {-# INLINE (<*>) #-}
 
 -- | A combination is 'Pure' only either part is.
@@ -104,6 +118,13 @@
     Other x <|> Other y = Other (x <|> y)
     {-# INLINE (<|>) #-}
 
+#if MIN_VERSION_base(4,18,0)
+instance (Foldable1 f) => Foldable1 (Lift f) where
+    foldMap1 f (Pure x)  = f x
+    foldMap1 f (Other y) = foldMap1 f y
+    {-# INLINE foldMap1 #-}
+#endif
+
 -- | Projection to the other functor.
 unLift :: (Applicative f) => Lift f a -> f a
 unLift (Pure x) = pure x
@@ -116,10 +137,22 @@
 mapLift f (Other e) = Other (f e)
 {-# INLINE mapLift #-}
 
+-- | Eliminator for 'Lift'.
+--
+-- * @'elimLift' f g . 'pure' = f@
+--
+-- * @'elimLift' f g . 'Other' = g@
+--
+elimLift :: (a -> r) -> (f a -> r) -> Lift f a -> r
+elimLift f _ (Pure x) = f x
+elimLift _ g (Other e) = g e
+{-# INLINE elimLift #-}
+
 -- | An applicative functor that collects a monoid (e.g. lists) of errors.
 -- A sequence of computations fails if any of its components do, but
--- unlike monads made with 'ExceptT' from "Control.Monad.Trans.Except",
--- these computations continue after an error, collecting all the errors.
+-- unlike monads made with 'Control.Monad.Trans.Except.ExceptT' from
+-- "Control.Monad.Trans.Except", these computations continue after an
+-- error, collecting all the errors.
 --
 -- * @'pure' f '<*>' 'pure' x = 'pure' (f x)@
 --
@@ -146,3 +179,7 @@
 failure :: e -> Errors e a
 failure e = Other (Constant e)
 {-# INLINE failure #-}
+
+-- | Convert from 'Either' to 'Errors' (inverse of 'runErrors').
+eitherToErrors :: Either e a -> Errors e a
+eitherToErrors = either failure Pure
diff --git a/Control/Monad/Signatures.hs b/Control/Monad/Signatures.hs
--- a/Control/Monad/Signatures.hs
+++ b/Control/Monad/Signatures.hs
@@ -27,23 +27,27 @@
 -- introduced in "Control.Monad.Trans.Cont".
 -- Any lifting function @liftCallCC@ should satisfy
 --
--- * @'lift' (f k) = f' ('lift' . k) => 'lift' (cf f) = liftCallCC cf f'@
+-- @'Control.Monad.Trans.Class.lift' (f k) = f' ('Control.Monad.Trans.Class.lift' . k) => 'Control.Monad.Trans.Class.lift' (cf f) = liftCallCC cf f'@
 --
+-- This implies that on entry to the continuation any outer monad
+-- transformer effect inside @callCC@ will have been rolled back.
 type CallCC m a b = ((a -> m b) -> m a) -> m a
 
 -- | Signature of the @catchE@ operation,
 -- introduced in "Control.Monad.Trans.Except".
 -- Any lifting function @liftCatch@ should satisfy
 --
--- * @'lift' (cf m f) = liftCatch ('lift' . cf) ('lift' f)@
+-- @'Control.Monad.Trans.Class.lift' (cf m h) = liftCatch cf ('Control.Monad.Trans.Class.lift' m) ('Control.Monad.Trans.Class.lift' . h)@
 --
+-- This implies that on entry to the handler function any outer monad
+-- transformer effect inside @catchE@ will have been rolled back.
 type Catch e m a = m a -> (e -> m a) -> m a
 
 -- | Signature of the @listen@ operation,
 -- introduced in "Control.Monad.Trans.Writer".
 -- Any lifting function @liftListen@ should satisfy
 --
--- * @'lift' . liftListen = liftListen . 'lift'@
+-- @'Control.Monad.Trans.Class.lift' . liftListen = liftListen . 'Control.Monad.Trans.Class.lift'@
 --
 type Listen w m a = m a -> m (a, w)
 
@@ -51,6 +55,6 @@
 -- introduced in "Control.Monad.Trans.Writer".
 -- Any lifting function @liftPass@ should satisfy
 --
--- * @'lift' . liftPass = liftPass . 'lift'@
+-- @'Control.Monad.Trans.Class.lift' . liftPass = liftPass . 'Control.Monad.Trans.Class.lift'@
 --
 type Pass w m a =  m (a, w -> w) -> m a
diff --git a/Control/Monad/Trans/Accum.hs b/Control/Monad/Trans/Accum.hs
new file mode 100644
--- /dev/null
+++ b/Control/Monad/Trans/Accum.hs
@@ -0,0 +1,319 @@
+{-# LANGUAGE CPP #-}
+#if __GLASGOW_HASKELL__ >= 702
+{-# LANGUAGE Safe #-}
+{-# LANGUAGE DeriveGeneric #-}
+#endif
+#if __GLASGOW_HASKELL__ >= 710 && __GLASGOW_HASKELL__ < 802
+{-# LANGUAGE AutoDeriveTypeable #-}
+#endif
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Control.Monad.Trans.Accum
+-- Copyright   :  (c) Nickolay Kudasov 2016
+-- License     :  BSD-style (see the file LICENSE)
+--
+-- Maintainer  :  R.Paterson@city.ac.uk
+-- Stability   :  experimental
+-- Portability :  portable
+--
+-- The lazy 'AccumT' monad transformer, which adds accumulation
+-- capabilities (such as declarations or document patches) to a given monad.
+-- Each computation has access to the combination of the input environment
+-- and outputs added so far, and returns the outputs added.
+--
+-- In applications requiring only the ability to accumulate an output and
+-- to inspect the output so far, it would be considerably more efficient
+-- to use "Control.Monad.Trans.State" instead.
+-----------------------------------------------------------------------------
+
+module Control.Monad.Trans.Accum (
+    -- * The Accum monad
+    Accum,
+    accum,
+    runAccum,
+    execAccum,
+    evalAccum,
+    mapAccum,
+    -- * The AccumT monad transformer
+    AccumT(..),
+    execAccumT,
+    evalAccumT,
+    mapAccumT,
+    -- * Accum operations
+    look,
+    looks,
+    add,
+    -- * Lifting other operations
+    liftCallCC,
+    liftCallCC',
+    liftCatch,
+    liftListen,
+    liftPass,
+    -- * Monad transformations
+    readerToAccumT,
+    writerToAccumT,
+    accumToStateT,
+  ) where
+
+import Control.Monad.IO.Class
+import Control.Monad.Trans.Class
+import Control.Monad.Trans.Reader (ReaderT(..))
+import Control.Monad.Trans.Writer (WriterT(..))
+import Control.Monad.Trans.State  (StateT(..))
+import Data.Functor.Identity
+
+import Control.Applicative
+import Control.Monad
+#if MIN_VERSION_base(4,9,0)
+import qualified Control.Monad.Fail as Fail
+#endif
+import Control.Monad.Fix
+import Control.Monad.Signatures
+#if !MIN_VERSION_base(4,8,0)
+import Data.Monoid
+#endif
+#if __GLASGOW_HASKELL__ >= 704
+import GHC.Generics
+#endif
+
+-- ---------------------------------------------------------------------------
+-- | An accumulation monad (non-strict) parameterized by the type @w@
+-- of output to accumulate.
+--
+-- This monad is a more complex extension of both the reader and writer
+-- monads.  The 'return' function produces the output 'mempty', while @m
+-- '>>=' k@ uses the output of @m@ both to extend the initial environment
+-- of @k@ and to combine with the output of @k@:
+--
+-- <<images/bind-AccumT.svg>>
+--
+-- In applications requiring only the ability to accumulate an output and
+-- to inspect the output so far, it would be considerably more efficient
+-- to use a state monad.
+type Accum w = AccumT w Identity
+
+-- | Construct an accumulation computation from a (result, output) pair.
+-- (The inverse of 'runAccum'.)
+accum :: (Monad m) => (w -> (a, w)) -> AccumT w m a
+accum f = AccumT $ \ w -> return (f w)
+{-# INLINE accum #-}
+
+-- | Unwrap an accumulation computation as a (result, output) pair.
+-- (The inverse of 'accum'.)
+runAccum :: Accum w a -> w -> (a, w)
+runAccum m = runIdentity . runAccumT m
+{-# INLINE runAccum #-}
+
+-- | Extract the output from an accumulation computation.
+--
+-- * @'execAccum' m w = 'snd' ('runAccum' m w)@
+execAccum :: Accum w a -> w -> w
+execAccum m w = snd (runAccum m w)
+{-# INLINE execAccum #-}
+
+-- | Evaluate an accumulation computation with the given initial output history
+-- and return the final value, discarding the final output.
+--
+-- * @'evalAccum' m w = 'fst' ('runAccum' m w)@
+evalAccum :: (Monoid w) => Accum w a -> w -> a
+evalAccum m w = fst (runAccum m w)
+{-# INLINE evalAccum #-}
+
+-- | Map both the return value and output of a computation using
+-- the given function.
+--
+-- * @'runAccum' ('mapAccum' f m) = f . 'runAccum' m@
+mapAccum :: ((a, w) -> (b, w)) -> Accum w a -> Accum w b
+mapAccum f = mapAccumT (Identity . f . runIdentity)
+{-# INLINE mapAccum #-}
+
+-- ---------------------------------------------------------------------------
+-- | An accumulation monad parameterized by:
+--
+--   * @w@ - the output to accumulate.
+--
+--   * @m@ - The inner monad.
+--
+-- This monad transformer is a more complex extension of both the reader
+-- and writer monad transformers.  The 'return' function produces the
+-- output 'mempty', while @m '>>=' k@ uses the output of @m@ both to
+-- extend the initial environment of @k@ and to combine with the output
+-- of @k@:
+--
+-- <<images/bind-AccumT.svg>>
+--
+-- In applications requiring only the ability to accumulate an output and
+-- to inspect the output so far, it would be considerably more efficient
+-- to use a state monad transformer.
+--
+-- @AccumT w m@ is strict if and only if @m@ is.
+newtype AccumT w m a = AccumT {
+    -- | Unwrap an accumulation computation.  For example, in the call
+    --
+    -- @    (value, locals) <- runAccumT action globals@
+    --
+    -- the action is fed an initial environment @globals@, and @locals@ is
+    -- the sum of all arguments to calls of 'add' executed by the action.
+    runAccumT :: w -> m (a, w)
+    }
+#if __GLASGOW_HASKELL__ >= 704
+    deriving (Generic)
+#endif
+
+-- | Extract the output from an accumulation computation.
+--
+-- * @'execAccumT' m w = 'liftM' 'snd' ('runAccumT' m w)@
+execAccumT :: (Monad m) => AccumT w m a -> w -> m w
+execAccumT m w = do
+    ~(_, w') <- runAccumT m w
+    return w'
+{-# INLINE execAccumT #-}
+
+-- | Evaluate an accumulation computation with the given initial output
+-- history and return the final value, discarding the final output.
+--
+-- * @'evalAccumT' m w = 'liftM' 'fst' ('runAccumT' m w)@
+evalAccumT :: (Monad m, Monoid w) => AccumT w m a -> w -> m a
+evalAccumT m w = do
+    ~(a, _) <- runAccumT m w
+    return a
+{-# INLINE evalAccumT #-}
+
+-- | Map both the return value and output of a computation using the
+-- given function.
+--
+-- * @'runAccumT' ('mapAccumT' f m) = f . 'runAccumT' m@
+mapAccumT :: (m (a, w) -> n (b, w)) -> AccumT w m a -> AccumT w n b
+mapAccumT f m = AccumT (f . runAccumT m)
+{-# INLINE mapAccumT #-}
+
+instance (Functor m) => Functor (AccumT w m) where
+    fmap f = mapAccumT $ fmap $ \ ~(a, w) -> (f a, w)
+    {-# INLINE fmap #-}
+
+instance (Monoid w, Functor m, Monad m) => Applicative (AccumT w m) where
+    pure a  = AccumT $ const $ return (a, mempty)
+    {-# INLINE pure #-}
+    mf <*> mv = AccumT $ \ w -> do
+      ~(f, w')  <- runAccumT mf w
+      ~(v, w'') <- runAccumT mv (w `mappend` w')
+      return (f v, w' `mappend` w'')
+    {-# INLINE (<*>) #-}
+
+instance (Monoid w, Functor m, MonadPlus m) => Alternative (AccumT w m) where
+    empty   = AccumT $ const mzero
+    {-# INLINE empty #-}
+    m <|> n = AccumT $ \ w -> runAccumT m w `mplus` runAccumT n w
+    {-# INLINE (<|>) #-}
+
+instance (Monoid w, Functor m, Monad m) => Monad (AccumT w m) where
+#if !(MIN_VERSION_base(4,8,0))
+    return a  = AccumT $ const $ return (a, mempty)
+    {-# INLINE return #-}
+#endif
+    m >>= k  = AccumT $ \ w -> do
+        ~(a, w')  <- runAccumT m w
+        ~(b, w'') <- runAccumT (k a) (w `mappend` w')
+        return (b, w' `mappend` w'')
+    {-# INLINE (>>=) #-}
+#if !(MIN_VERSION_base(4,13,0))
+    fail msg = AccumT $ const (fail msg)
+    {-# INLINE fail #-}
+#endif
+
+#if MIN_VERSION_base(4,9,0)
+instance (Monoid w, Fail.MonadFail m) => Fail.MonadFail (AccumT w m) where
+    fail msg = AccumT $ const (Fail.fail msg)
+    {-# INLINE fail #-}
+#endif
+
+instance (Monoid w, Functor m, MonadPlus m) => MonadPlus (AccumT w m) where
+    mzero       = AccumT $ const mzero
+    {-# INLINE mzero #-}
+    m `mplus` n = AccumT $ \ w -> runAccumT m w `mplus` runAccumT n w
+    {-# INLINE mplus #-}
+
+instance (Monoid w, Functor m, MonadFix m) => MonadFix (AccumT w m) where
+    mfix m = AccumT $ \ w -> mfix $ \ ~(a, _) -> runAccumT (m a) w
+    {-# INLINE mfix #-}
+
+instance (Monoid w) => MonadTrans (AccumT w) where
+    lift m = AccumT $ const $ do
+        a <- m
+        return (a, mempty)
+    {-# INLINE lift #-}
+
+instance (Monoid w, Functor m, MonadIO m) => MonadIO (AccumT w m) where
+    liftIO = lift . liftIO
+    {-# INLINE liftIO #-}
+
+-- | @'look'@ is an action that fetches all the previously accumulated output.
+look :: (Monoid w, Monad m) => AccumT w m w
+look = AccumT $ \ w -> return (w, mempty)
+
+-- | @'look'@ is an action that retrieves a function of the previously accumulated output.
+looks :: (Monoid w, Monad m) => (w -> a) -> AccumT w m a
+looks f = AccumT $ \ w -> return (f w, mempty)
+
+-- | @'add' w@ is an action that produces the output @w@.
+add :: (Monad m) => w -> AccumT w m ()
+add w = accum $ const ((), w)
+{-# INLINE add #-}
+
+-- | Uniform lifting of a @callCC@ operation to the new monad.
+-- This version rolls back to the original output history on entering the
+-- continuation.
+liftCallCC :: CallCC m (a, w) (b, w) -> CallCC (AccumT w m) a b
+liftCallCC callCC f = AccumT $ \ w ->
+    callCC $ \ c ->
+    runAccumT (f (\ a -> AccumT $ \ _ -> c (a, w))) w
+{-# INLINE liftCallCC #-}
+
+-- | In-situ lifting of a @callCC@ operation to the new monad.
+-- This version uses the current output history on entering the continuation.
+-- It does not satisfy the uniformity property (see "Control.Monad.Signatures").
+liftCallCC' :: CallCC m (a, w) (b, w) -> CallCC (AccumT w m) a b
+liftCallCC' callCC f = AccumT $ \ s ->
+    callCC $ \ c ->
+    runAccumT (f (\ a -> AccumT $ \ s' -> c (a, s'))) s
+{-# INLINE liftCallCC' #-}
+
+-- | Lift a @catchE@ operation to the new monad.
+-- The uniformity property (see "Control.Monad.Signatures") implies that
+-- the lifted @catchE@ discards any output from the body on entering
+-- the handler.
+liftCatch :: Catch e m (a, w) -> Catch e (AccumT w m) a
+liftCatch catchE m h =
+    AccumT $ \ w -> runAccumT m w `catchE` \ e -> runAccumT (h e) w
+{-# INLINE liftCatch #-}
+
+-- | Lift a @listen@ operation to the new monad.
+liftListen :: (Monad m) => Listen w m (a, s) -> Listen w (AccumT s m) a
+liftListen listen m = AccumT $ \ s -> do
+    ~((a, s'), w) <- listen (runAccumT m s)
+    return ((a, w), s')
+{-# INLINE liftListen #-}
+
+-- | Lift a @pass@ operation to the new monad.
+liftPass :: (Monad m) => Pass w m (a, s) -> Pass w (AccumT s m) a
+liftPass pass m = AccumT $ \ s -> pass $ do
+    ~((a, f), s') <- runAccumT m s
+    return ((a, s'), f)
+{-# INLINE liftPass #-}
+
+-- | Convert a read-only computation into an accumulation computation.
+readerToAccumT :: (Functor m, Monoid w) => ReaderT w m a -> AccumT w m a
+readerToAccumT (ReaderT f) = AccumT $ \ w -> fmap (\ a -> (a, mempty)) (f w)
+{-# INLINE readerToAccumT #-}
+
+-- | Convert a writer computation into an accumulation computation.
+writerToAccumT :: WriterT w m a -> AccumT w m a
+writerToAccumT (WriterT m) = AccumT $ const $ m
+{-# INLINE writerToAccumT #-}
+
+-- | Convert an accumulation (append-only) computation into a fully
+-- stateful computation.
+accumToStateT :: (Functor m, Monoid s) => AccumT s m a -> StateT s m a
+accumToStateT (AccumT f) =
+    StateT $ \ w -> fmap (\ ~(a, w') -> (a, w `mappend` w')) (f w)
+{-# INLINE accumToStateT #-}
diff --git a/Control/Monad/Trans/Class.hs b/Control/Monad/Trans/Class.hs
--- a/Control/Monad/Trans/Class.hs
+++ b/Control/Monad/Trans/Class.hs
@@ -2,9 +2,12 @@
 #if __GLASGOW_HASKELL__ >= 702
 {-# LANGUAGE Safe #-}
 #endif
-#if __GLASGOW_HASKELL__ >= 710
+#if __GLASGOW_HASKELL__ >= 710 && __GLASGOW_HASKELL__ < 802
 {-# LANGUAGE AutoDeriveTypeable #-}
 #endif
+#if __GLASGOW_HASKELL__ >= 806
+{-# LANGUAGE QuantifiedConstraints #-}
+#endif
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Control.Monad.Trans.Class
@@ -46,35 +49,65 @@
     -- $example3
   ) where
 
--- | The class of monad transformers.  Instances should satisfy the
--- following laws, which state that 'lift' is a monad transformation:
+-- | The class of monad transformers.
+-- For any monad @m@, the result @t m@ should also be a monad,
+-- and 'lift' should be a monad transformation from @m@ to @t m@,
+-- i.e. it should satisfy the following laws:
 --
 -- * @'lift' . 'return' = 'return'@
 --
 -- * @'lift' (m >>= f) = 'lift' m >>= ('lift' . f)@
-
+--
+-- Since 0.6.0.0 and for GHC 8.6 and later, the requirement that @t m@
+-- be a 'Monad' is enforced by the implication constraint
+-- @forall m. 'Monad' m => 'Monad' (t m)@ enabled by the
+-- @QuantifiedConstraints@ extension.
+--
+-- === __Ambiguity error with GHC 9.0 to 9.2.2__
+-- These versions of GHC have a bug
+-- (<https://gitlab.haskell.org/ghc/ghc/-/issues/20582>)
+-- which causes constraints like
+--
+-- @
+-- (MonadTrans t, forall m. Monad m => Monad (t m)) => ...
+-- @
+--
+-- to be reported as ambiguous.  For transformers 0.6 and later, this can
+-- be fixed by removing the second constraint, which is implied by the first.
+#if __GLASGOW_HASKELL__ >= 806
+class (forall m. Monad m => Monad (t m)) => MonadTrans t where
+#else
+-- Prior to GHC 8.8 (base-4.13), the Monad class included fail.
+-- GHC 8.6 (base-4.12) has MonadFailDesugaring on by default, so there
+-- is no need for users defining monad transformers to define fail in
+-- the Monad instance of the transformed monad.
 class MonadTrans t where
+#endif
     -- | Lift a computation from the argument monad to the constructed monad.
     lift :: (Monad m) => m a -> t m a
 
 {- $conventions
-Most monad transformer modules include the special case of applying
-the transformer to 'Data.Functor.Identity.Identity'.  For example,
+All monad transformer modules except 'Control.Monad.Trans.Maybe'
+include the special case of applying the transformer
+to 'Data.Functor.Identity.Identity'.  For example,
 @'Control.Monad.Trans.State.Lazy.State' s@ is an abbreviation for
 @'Control.Monad.Trans.State.Lazy.StateT' s 'Data.Functor.Identity.Identity'@.
+As a consequence, operations defined on the monad transformer can also
+be used on this special case.
 
 Each monad transformer also comes with an operation @run@/XXX/@T@ to
 unwrap the transformer, exposing a computation of the inner monad.
-(Currently these functions are defined as field labels, but in the next
-major release they will be separate functions.)
+(Currently these functions are defined as field labels, but in a future
+major release they may be separate functions.)
 
 All of the monad transformers except 'Control.Monad.Trans.Cont.ContT'
-are functors on the category of monads: in addition to defining a
-mapping of monads, they also define a mapping from transformations
-between base monads to transformations between transformed monads,
-called @map@/XXX/@T@.  Thus given a monad transformation @t :: M a -> N a@,
-the combinator 'Control.Monad.Trans.State.Lazy.mapStateT' constructs
-a monad transformation
+and 'Control.Monad.Trans.Cont.SelectT' are functors on the category
+of monads: in addition to defining a mapping of monads, they
+also define a mapping from transformations between base monads to
+transformations between transformed monads, called @map@/XXX/@T@.
+Thus given a monad transformation @t :: M a -> N a@, the combinator
+'Control.Monad.Trans.State.Lazy.mapStateT' constructs a monad
+transformation
 
 > mapStateT t :: StateT s M a -> StateT s N a
 
@@ -93,26 +126,39 @@
 
 {- $strict
 
-A monad is said to be /strict/ if its '>>=' operation is strict in its first
-argument.  The base monads 'Maybe', @[]@ and 'IO' are strict:
+A monad is said to be /strict/ if its '>>=' operation (and therefore also
+'>>') is strict in its first argument.  The base monads 'Maybe', @[]@
+and 'IO' are strict:
 
->>> undefined >> return 2 :: Maybe Integer
+>>> undefined >> Just 2
 *** Exception: Prelude.undefined
+>>> undefined >> [2]
+*** Exception: Prelude.undefined
+>>> undefined >> print 2
+*** Exception: Prelude.undefined
 
-However the monad 'Data.Functor.Identity.Identity' is not:
+However, the monads 'Data.Functor.Identity.Identity' and @(->) a@ are not:
 
->>> runIdentity (undefined >> return 2)
-2
+>>> undefined >> Identity 2
+Identity 2
+>>> (undefined >> (+1)) 5
+6
 
 In a strict monad you know when each action is executed, but the monad
 is not necessarily strict in the return value, or in other components
-of the monad, such as a state.  However you can use 'seq' to create
+of the monad, such as a state.  However, you can use 'seq' to create
 an action that is strict in the component you want evaluated.
 -}
 
 {- $example1
 
-One might define a parsing monad by adding a state (the 'String' remaining
+The first example is a parser monad in the style of
+
+* \"Monadic parsing in Haskell\", by Graham Hutton and Erik Meijer,
+/Journal of Functional Programming/ 8(4):437-444, July 1998
+(<http://www.cs.nott.ac.uk/~pszgmh/bib.html#pearl>).
+
+We can define such a parser monad by adding a state (the 'String' remaining
 to be parsed) to the @[]@ monad, which provides non-determinism:
 
 > import Control.Monad.Trans.State
@@ -188,7 +234,8 @@
 {- $example3
 
 This example is a cut-down version of the one in
-\"Monad Transformers and Modular Interpreters\",
+
+* \"Monad Transformers and Modular Interpreters\",
 by Sheng Liang, Paul Hudak and Mark Jones in /POPL'95/
 (<http://web.cecs.pdx.edu/~mpj/pubs/modinterp.html>).
 
diff --git a/Control/Monad/Trans/Cont.hs b/Control/Monad/Trans/Cont.hs
--- a/Control/Monad/Trans/Cont.hs
+++ b/Control/Monad/Trans/Cont.hs
@@ -1,11 +1,12 @@
 {-# LANGUAGE CPP #-}
 #if __GLASGOW_HASKELL__ >= 702
 {-# LANGUAGE Safe #-}
+{-# LANGUAGE DeriveGeneric #-}
 #endif
 #if __GLASGOW_HASKELL__ >= 706
 {-# LANGUAGE PolyKinds #-}
 #endif
-#if __GLASGOW_HASKELL__ >= 710
+#if __GLASGOW_HASKELL__ >= 710 && __GLASGOW_HASKELL__ < 802
 {-# LANGUAGE AutoDeriveTypeable #-}
 #endif
 -----------------------------------------------------------------------------
@@ -52,15 +53,21 @@
 import Control.Monad.Trans.Class
 import Data.Functor.Identity
 
+#if !(MIN_VERSION_base(4,8,0))
 import Control.Applicative
+#endif
 #if MIN_VERSION_base(4,9,0)
 import qualified Control.Monad.Fail as Fail
 #endif
+#if __GLASGOW_HASKELL__ >= 704
+import GHC.Generics
+#endif
 
 {- |
-Continuation monad.
-@Cont r a@ is a CPS computation that produces an intermediate result
-of type @a@ within a CPS computation whose final result type is @r@.
+The continuation monad, which is non-strict.
+@Cont r a@ is a CPS ("continuation-passing style") computation that produces an
+intermediate result of type @a@ within a CPS computation whose final result type
+is @r@.
 
 The @return@ function simply creates a continuation which passes the value on.
 
@@ -132,7 +139,12 @@
 --
 -- 'ContT' is not a functor on the category of monads, and many operations
 -- cannot be lifted through it.
+--
+-- @ContT r m@ is strict if and only if @m@ is.
 newtype ContT r m a = ContT { runContT :: (a -> m r) -> m r }
+#if __GLASGOW_HASKELL__ >= 704
+    deriving (Generic)
+#endif
 
 -- | The result of running a CPS computation with 'return' as the
 -- final continuation.
@@ -169,6 +181,8 @@
     {-# INLINE pure #-}
     f <*> v = ContT $ \ c -> runContT f $ \ g -> runContT v (c . g)
     {-# INLINE (<*>) #-}
+    m *> k = m >>= \_ -> k
+    {-# INLINE (*>) #-}
 
 instance Monad (ContT r m) where
 #if !(MIN_VERSION_base(4,8,0))
diff --git a/Control/Monad/Trans/Error.hs b/Control/Monad/Trans/Error.hs
deleted file mode 100644
--- a/Control/Monad/Trans/Error.hs
+++ /dev/null
@@ -1,323 +0,0 @@
-{-# LANGUAGE CPP #-}
-#if __GLASGOW_HASKELL__ >= 702
-{-# LANGUAGE Safe #-}
-#endif
-#if __GLASGOW_HASKELL__ >= 710
-{-# LANGUAGE AutoDeriveTypeable #-}
-#endif
-#if !(MIN_VERSION_base(4,9,0))
-{-# OPTIONS_GHC -fno-warn-orphans #-}
-#endif
------------------------------------------------------------------------------
--- |
--- Module      :  Control.Monad.Trans.Error
--- Copyright   :  (c) Michael Weber <michael.weber@post.rwth-aachen.de> 2001,
---                (c) Jeff Newbern 2003-2006,
---                (c) Andriy Palamarchuk 2006
--- License     :  BSD-style (see the file LICENSE)
---
--- Maintainer  :  R.Paterson@city.ac.uk
--- Stability   :  experimental
--- Portability :  portable
---
--- This monad transformer adds the ability to fail or throw exceptions
--- to a monad.
---
--- A sequence of actions succeeds, producing a value, only if all the
--- actions in the sequence are successful.  If one fails with an error,
--- the rest of the sequence is skipped and the composite action fails
--- with that error.
---
--- If the value of the error is not required, the variant in
--- "Control.Monad.Trans.Maybe" may be used instead.
---
--- /Note:/ This module will be removed in a future release.
--- Instead, use "Control.Monad.Trans.Except", which does not restrict
--- the exception type, and also includes a base exception monad.
------------------------------------------------------------------------------
-
-module Control.Monad.Trans.Error
-  {-# DEPRECATED "Use Control.Monad.Trans.Except instead" #-} (
-    -- * The ErrorT monad transformer
-    Error(..),
-    ErrorList(..),
-    ErrorT(..),
-    mapErrorT,
-    -- * Error operations
-    throwError,
-    catchError,
-    -- * Lifting other operations
-    liftCallCC,
-    liftListen,
-    liftPass,
-    -- * Examples
-    -- $examples
-  ) where
-
-import Control.Monad.IO.Class
-import Control.Monad.Signatures
-import Control.Monad.Trans.Class
-import Data.Functor.Classes
-
-import Control.Applicative
-import Control.Exception (IOException)
-import Control.Monad
-#if MIN_VERSION_base(4,9,0)
-import qualified Control.Monad.Fail as Fail
-#endif
-import Control.Monad.Fix
-#if !(MIN_VERSION_base(4,6,0))
-import Control.Monad.Instances ()  -- deprecated from base-4.6
-#endif
-import Data.Foldable (Foldable(foldMap))
-import Data.Monoid (mempty)
-import Data.Traversable (Traversable(traverse))
-import System.IO.Error
-
-#if !(MIN_VERSION_base(4,9,0))
--- These instances are in base-4.9.0
-
-instance MonadPlus IO where
-    mzero       = ioError (userError "mzero")
-    m `mplus` n = m `catchIOError` \ _ -> n
-
-instance Alternative IO where
-    empty = mzero
-    (<|>) = mplus
-
-# if !(MIN_VERSION_base(4,4,0))
--- exported by System.IO.Error from base-4.4
-catchIOError :: IO a -> (IOError -> IO a) -> IO a
-catchIOError = catch
-# endif
-#endif
-
-instance (Error e) => Alternative (Either e) where
-    empty        = Left noMsg
-    Left _ <|> n = n
-    m      <|> _ = m
-
-instance (Error e) => MonadPlus (Either e) where
-    mzero            = Left noMsg
-    Left _ `mplus` n = n
-    m      `mplus` _ = m
-
-#if !(MIN_VERSION_base(4,3,0))
--- These instances are in base-4.3
-
-instance Applicative (Either e) where
-    pure          = Right
-    Left  e <*> _ = Left e
-    Right f <*> r = fmap f r
-
-instance Monad (Either e) where
-    return        = Right
-    Left  l >>= _ = Left l
-    Right r >>= k = k r
-
-instance MonadFix (Either e) where
-    mfix f = let
-        a = f $ case a of
-            Right r -> r
-            _       -> error "empty mfix argument"
-        in a
-
-#endif /* base to 4.2.0.x */
-
--- | An exception to be thrown.
---
--- Minimal complete definition: 'noMsg' or 'strMsg'.
-class Error a where
-    -- | Creates an exception without a message.
-    -- The default implementation is @'strMsg' \"\"@.
-    noMsg  :: a
-    -- | Creates an exception with a message.
-    -- The default implementation of @'strMsg' s@ is 'noMsg'.
-    strMsg :: String -> a
-
-    noMsg    = strMsg ""
-    strMsg _ = noMsg
-
-instance Error IOException where
-    strMsg = userError
-
--- | A string can be thrown as an error.
-instance (ErrorList a) => Error [a] where
-    strMsg = listMsg
-
--- | Workaround so that we can have a Haskell 98 instance @'Error' 'String'@.
-class ErrorList a where
-    listMsg :: String -> [a]
-
-instance ErrorList Char where
-    listMsg = id
-
--- | The error monad transformer. It can be used to add error handling
--- to other monads.
---
--- The @ErrorT@ Monad structure is parameterized over two things:
---
--- * e - The error type.
---
--- * m - The inner monad.
---
--- The 'return' function yields a successful computation, while @>>=@
--- sequences two subcomputations, failing on the first error.
-newtype ErrorT e m a = ErrorT { runErrorT :: m (Either e a) }
-
-instance (Eq e, Eq1 m) => Eq1 (ErrorT e m) where
-    liftEq eq (ErrorT x) (ErrorT y) = liftEq (liftEq eq) x y
-
-instance (Ord e, Ord1 m) => Ord1 (ErrorT e m) where
-    liftCompare comp (ErrorT x) (ErrorT y) = liftCompare (liftCompare comp) x y
-
-instance (Read e, Read1 m) => Read1 (ErrorT e m) where
-    liftReadsPrec rp rl = readsData $
-        readsUnaryWith (liftReadsPrec rp' rl') "ErrorT" ErrorT
-      where
-        rp' = liftReadsPrec rp rl
-        rl' = liftReadList rp rl
-
-instance (Show e, Show1 m) => Show1 (ErrorT e m) where
-    liftShowsPrec sp sl d (ErrorT m) =
-        showsUnaryWith (liftShowsPrec sp' sl') "ErrorT" d m
-      where
-        sp' = liftShowsPrec sp sl
-        sl' = liftShowList sp sl
-
-instance (Eq e, Eq1 m, Eq a) => Eq (ErrorT e m a) where (==) = eq1
-instance (Ord e, Ord1 m, Ord a) => Ord (ErrorT e m a) where compare = compare1
-instance (Read e, Read1 m, Read a) => Read (ErrorT e m a) where
-    readsPrec = readsPrec1
-instance (Show e, Show1 m, Show a) => Show (ErrorT e m a) where
-    showsPrec = showsPrec1
-
--- | Map the unwrapped computation using the given function.
---
--- * @'runErrorT' ('mapErrorT' f m) = f ('runErrorT' m)@
-mapErrorT :: (m (Either e a) -> n (Either e' b))
-          -> ErrorT e m a
-          -> ErrorT e' n b
-mapErrorT f m = ErrorT $ f (runErrorT m)
-
-instance (Functor m) => Functor (ErrorT e m) where
-    fmap f = ErrorT . fmap (fmap f) . runErrorT
-
-instance (Foldable f) => Foldable (ErrorT e f) where
-    foldMap f (ErrorT a) = foldMap (either (const mempty) f) a
-
-instance (Traversable f) => Traversable (ErrorT e f) where
-    traverse f (ErrorT a) =
-        ErrorT <$> traverse (either (pure . Left) (fmap Right . f)) a
-
-instance (Functor m, Monad m) => Applicative (ErrorT e m) where
-    pure a  = ErrorT $ return (Right a)
-    f <*> v = ErrorT $ do
-        mf <- runErrorT f
-        case mf of
-            Left  e -> return (Left e)
-            Right k -> do
-                mv <- runErrorT v
-                case mv of
-                    Left  e -> return (Left e)
-                    Right x -> return (Right (k x))
-
-instance (Functor m, Monad m, Error e) => Alternative (ErrorT e m) where
-    empty = mzero
-    (<|>) = mplus
-
-instance (Monad m, Error e) => Monad (ErrorT e m) where
-#if !(MIN_VERSION_base(4,8,0))
-    return a = ErrorT $ return (Right a)
-#endif
-    m >>= k  = ErrorT $ do
-        a <- runErrorT m
-        case a of
-            Left  l -> return (Left l)
-            Right r -> runErrorT (k r)
-    fail msg = ErrorT $ return (Left (strMsg msg))
-
-#if MIN_VERSION_base(4,9,0)
-instance (Monad m, Error e) => Fail.MonadFail (ErrorT e m) where
-    fail msg = ErrorT $ return (Left (strMsg msg))
-#endif
-
-instance (Monad m, Error e) => MonadPlus (ErrorT e m) where
-    mzero       = ErrorT $ return (Left noMsg)
-    m `mplus` n = ErrorT $ do
-        a <- runErrorT m
-        case a of
-            Left  _ -> runErrorT n
-            Right r -> return (Right r)
-
-instance (MonadFix m, Error e) => MonadFix (ErrorT e m) where
-    mfix f = ErrorT $ mfix $ \ a -> runErrorT $ f $ case a of
-        Right r -> r
-        _       -> error "empty mfix argument"
-
-instance MonadTrans (ErrorT e) where
-    lift m = ErrorT $ do
-        a <- m
-        return (Right a)
-
-instance (Error e, MonadIO m) => MonadIO (ErrorT e m) where
-    liftIO = lift . liftIO
-
--- | Signal an error value @e@.
---
--- * @'runErrorT' ('throwError' e) = 'return' ('Left' e)@
---
--- * @'throwError' e >>= m = 'throwError' e@
-throwError :: (Monad m) => e -> ErrorT e m a
-throwError l = ErrorT $ return (Left l)
-
--- | Handle an error.
---
--- * @'catchError' h ('lift' m) = 'lift' m@
---
--- * @'catchError' h ('throwError' e) = h e@
-catchError :: (Monad m) =>
-    ErrorT e m a                -- ^ the inner computation
-    -> (e -> ErrorT e m a)      -- ^ a handler for errors in the inner
-                                -- computation
-    -> ErrorT e m a
-m `catchError` h = ErrorT $ do
-    a <- runErrorT m
-    case a of
-        Left  l -> runErrorT (h l)
-        Right r -> return (Right r)
-
--- | Lift a @callCC@ operation to the new monad.
-liftCallCC :: CallCC m (Either e a) (Either e b) -> CallCC (ErrorT e m) a b
-liftCallCC callCC f = ErrorT $
-    callCC $ \ c ->
-    runErrorT (f (\ a -> ErrorT $ c (Right a)))
-
--- | Lift a @listen@ operation to the new monad.
-liftListen :: (Monad m) => Listen w m (Either e a) -> Listen w (ErrorT e m) a
-liftListen listen = mapErrorT $ \ m -> do
-    (a, w) <- listen m
-    return $! fmap (\ r -> (r, w)) a
-
--- | Lift a @pass@ operation to the new monad.
-liftPass :: (Monad m) => Pass w m (Either e a) -> Pass w (ErrorT e m) a
-liftPass pass = mapErrorT $ \ m -> pass $ do
-    a <- m
-    return $! case a of
-        Left  l      -> (Left  l, id)
-        Right (r, f) -> (Right r, f)
-
-{- $examples
-
-Wrapping an IO action that can throw an error @e@:
-
-> type ErrorWithIO e a = ErrorT e IO a
-> ==> ErrorT (IO (Either e a))
-
-An IO monad wrapped in @StateT@ inside of @ErrorT@:
-
-> type ErrorAndStateWithIO e s a = ErrorT e (StateT s IO) a
-> ==> ErrorT (StateT s IO (Either e a))
-> ==> ErrorT (StateT (s -> IO (Either e a,s)))
-
--}
diff --git a/Control/Monad/Trans/Except.hs b/Control/Monad/Trans/Except.hs
--- a/Control/Monad/Trans/Except.hs
+++ b/Control/Monad/Trans/Except.hs
@@ -1,8 +1,9 @@
 {-# LANGUAGE CPP #-}
 #if __GLASGOW_HASKELL__ >= 702
 {-# LANGUAGE Safe #-}
+{-# LANGUAGE DeriveGeneric #-}
 #endif
-#if __GLASGOW_HASKELL__ >= 710
+#if __GLASGOW_HASKELL__ >= 710 && __GLASGOW_HASKELL__ < 802
 {-# LANGUAGE AutoDeriveTypeable #-}
 #endif
 -----------------------------------------------------------------------------
@@ -15,7 +16,8 @@
 -- Stability   :  experimental
 -- Portability :  portable
 --
--- This monad transformer extends a monad with the ability throw exceptions.
+-- This monad transformer extends a monad with the ability to throw
+-- and catch exceptions.
 --
 -- A sequence of actions terminates normally, producing a value,
 -- only if none of the actions in the sequence throws an exception.
@@ -34,13 +36,16 @@
     mapExcept,
     withExcept,
     -- * The ExceptT monad transformer
-    ExceptT(ExceptT),
-    runExceptT,
+    ExceptT(..),
     mapExceptT,
     withExceptT,
     -- * Exception operations
     throwE,
     catchE,
+    handleE,
+    tryE,
+    finallyE,
+    onE,
     -- * Lifting other operations
     liftCallCC,
     liftListen,
@@ -51,6 +56,9 @@
 import Control.Monad.Signatures
 import Control.Monad.Trans.Class
 import Data.Functor.Classes
+#if MIN_VERSION_base(4,12,0)
+import Data.Functor.Contravariant
+#endif
 import Data.Functor.Identity
 
 import Control.Applicative
@@ -62,13 +70,20 @@
 #if MIN_VERSION_base(4,4,0)
 import Control.Monad.Zip (MonadZip(mzipWith))
 #endif
+#if !(MIN_VERSION_base(4,8,0)) || defined(__MHS__)
 import Data.Foldable (Foldable(foldMap))
-import Data.Monoid
+import Data.Monoid (Monoid(mempty, mappend))
 import Data.Traversable (Traversable(traverse))
+#endif
+#if __GLASGOW_HASKELL__ >= 704
+import GHC.Generics
+#endif
 
--- | The parameterizable exception monad.
+-- | The parameterizable exception monad, which is strict.
 --
--- Computations are either exceptions or normal values.
+-- Computations are either exceptions (of any type) or normal values.
+-- These computations are plain values, and are unrelated to the
+-- "Control.Exception" mechanism, which is tied to the 'IO' monad.
 --
 -- The 'return' function returns a normal value, while @>>=@ exits on
 -- the first exception.  For a variant that continues after an error
@@ -77,8 +92,8 @@
 
 -- | Constructor for computations in the exception monad.
 -- (The inverse of 'runExcept').
-except :: Either e a -> Except e a
-except m = ExceptT (Identity m)
+except :: (Monad m) => Either e a -> ExceptT e m a
+except m = ExceptT (return m)
 {-# INLINE except #-}
 
 -- | Extractor for computations in the exception monad.
@@ -104,16 +119,24 @@
 
 -- | A monad transformer that adds exceptions to other monads.
 --
--- @ExceptT@ constructs a monad parameterized over two things:
+-- @ExceptT@ constructs a strict monad parameterized over two things:
 --
--- * e - The exception type.
+-- * e - An arbitrary exception type.
 --
 -- * m - The inner monad.
 --
+-- The monadic computations are a plain values.  They are unrelated to
+-- the "Control.Exception" mechanism, which is tied to the 'IO' monad.
+--
 -- The 'return' function yields a computation that produces the given
 -- value, while @>>=@ sequences two subcomputations, exiting on the
 -- first exception.
-newtype ExceptT e m a = ExceptT (m (Either e a))
+newtype ExceptT e m a = ExceptT { runExceptT :: m (Either e a) }
+#if __GLASGOW_HASKELL__ >= 710
+    deriving (Generic, Generic1)
+#elif __GLASGOW_HASKELL__ >= 704
+    deriving (Generic)
+#endif
 
 instance (Eq e, Eq1 m) => Eq1 (ExceptT e m) where
     liftEq eq (ExceptT x) (ExceptT y) = liftEq (liftEq eq) x y
@@ -147,11 +170,6 @@
 instance (Show e, Show1 m, Show a) => Show (ExceptT e m a) where
     showsPrec = showsPrec1
 
--- | The inverse of 'ExceptT'.
-runExceptT :: ExceptT e m a -> m (Either e a)
-runExceptT (ExceptT m) = m
-{-# INLINE runExceptT #-}
-
 -- | Map the unwrapped computation using the given function.
 --
 -- * @'runExceptT' ('mapExceptT' f m) = f ('runExceptT' m)@
@@ -193,6 +211,8 @@
                     Left e -> return (Left e)
                     Right x -> return (Right (k x))
     {-# INLINEABLE (<*>) #-}
+    m *> k = m >>= \_ -> k
+    {-# INLINE (*>) #-}
 
 instance (Functor m, Monad m, Monoid e) => Alternative (ExceptT e m) where
     empty = ExceptT $ return (Left mempty)
@@ -215,8 +235,10 @@
             Left e -> return (Left e)
             Right x -> runExceptT (k x)
     {-# INLINE (>>=) #-}
+#if !(MIN_VERSION_base(4,13,0))
     fail = ExceptT . fail
     {-# INLINE fail #-}
+#endif
 
 #if MIN_VERSION_base(4,9,0)
 instance (Fail.MonadFail m) => Fail.MonadFail (ExceptT e m) where
@@ -253,6 +275,12 @@
     {-# INLINE mzipWith #-}
 #endif
 
+#if MIN_VERSION_base(4,12,0)
+instance Contravariant m => Contravariant (ExceptT e m) where
+    contramap f = ExceptT . contramap (fmap f) . runExceptT
+    {-# INLINE contramap #-}
+#endif
+
 -- | Signal an exception value @e@.
 --
 -- * @'runExceptT' ('throwE' e) = 'return' ('Left' e)@
@@ -264,9 +292,9 @@
 
 -- | Handle an exception.
 --
--- * @'catchE' h ('lift' m) = 'lift' m@
+-- * @'catchE' ('lift' m) h = 'lift' m@
 --
--- * @'catchE' h ('throwE' e) = h e@
+-- * @'catchE' ('throwE' e) h = h e@
 catchE :: (Monad m) =>
     ExceptT e m a               -- ^ the inner computation
     -> (e -> ExceptT e' m a)    -- ^ a handler for exceptions in the inner
@@ -278,6 +306,37 @@
         Left  l -> runExceptT (h l)
         Right r -> return (Right r)
 {-# INLINE catchE #-}
+
+-- | The same as @'flip' 'catchE'@, which is useful in situations where
+-- the code for the handler is shorter.
+handleE :: Monad m => (e -> ExceptT e' m a) -> ExceptT e m a -> ExceptT e' m a
+handleE = flip catchE
+{-# INLINE handleE #-}
+
+-- | Similar to 'catchE', but returns an 'Either' result which is
+-- @('Right' a)@ if no exception was thown, or @('Left' ex)@ if an
+-- exception @ex@ was thrown.
+tryE :: Monad m => ExceptT e m a -> ExceptT e m (Either e a)
+tryE m = catchE (liftM Right m) (return . Left)
+{-# INLINE tryE #-}
+
+-- | @'finallyE' a b@ executes computation @a@ followed by computation @b@,
+-- even if @a@ exits early by throwing an exception.  In the latter case,
+-- the exception is re-thrown after @b@ has been executed.
+finallyE :: Monad m => ExceptT e m a -> ExceptT e m () -> ExceptT e m a
+finallyE m closer = do
+    res <- tryE m
+    closer
+    either throwE return res
+{-# INLINE finallyE #-}
+
+-- | If the first action succeeds, return its value, ignoring the
+-- second action.  If the first action throws an exception, run the
+-- second action and then throw an exception, either the one thrown by
+-- the second action, if any, or the one thrown by the first action.
+onE :: (Monad m) => ExceptT e m a -> ExceptT e m b -> ExceptT e m a
+onE action1 action2 = action1 `catchE` \ e -> action2 >> throwE e
+{-# INLINE onE #-}
 
 -- | Lift a @callCC@ operation to the new monad.
 liftCallCC :: CallCC m (Either e a) (Either e b) -> CallCC (ExceptT e m) a b
diff --git a/Control/Monad/Trans/Identity.hs b/Control/Monad/Trans/Identity.hs
--- a/Control/Monad/Trans/Identity.hs
+++ b/Control/Monad/Trans/Identity.hs
@@ -1,11 +1,12 @@
 {-# LANGUAGE CPP #-}
 #if __GLASGOW_HASKELL__ >= 702
 {-# LANGUAGE Safe #-}
+{-# LANGUAGE DeriveGeneric #-}
 #endif
 #if __GLASGOW_HASKELL__ >= 706
 {-# LANGUAGE PolyKinds #-}
 #endif
-#if __GLASGOW_HASKELL__ >= 710
+#if __GLASGOW_HASKELL__ >= 710 && __GLASGOW_HASKELL__ < 802
 {-# LANGUAGE AutoDeriveTypeable #-}
 #endif
 -----------------------------------------------------------------------------
@@ -35,7 +36,13 @@
 import Control.Monad.IO.Class (MonadIO(liftIO))
 import Control.Monad.Signatures
 import Control.Monad.Trans.Class (MonadTrans(lift))
+#if MIN_VERSION_base(4,18,0)
+import Data.Foldable1 (Foldable1(foldMap1))
+#endif
 import Data.Functor.Classes
+#if MIN_VERSION_base(4,12,0)
+import Data.Functor.Contravariant
+#endif
 
 import Control.Applicative
 import Control.Monad (MonadPlus(mzero, mplus))
@@ -46,11 +53,22 @@
 #if MIN_VERSION_base(4,4,0)
 import Control.Monad.Zip (MonadZip(mzipWith))
 #endif
-import Data.Foldable (Foldable(foldMap))
+import Data.Foldable
+#if !(MIN_VERSION_base(4,8,0)) || defined(__MHS__)
 import Data.Traversable (Traversable(traverse))
+#endif
+import Prelude hiding (foldr, foldr1, foldl, foldl1, null, length)
+#if __GLASGOW_HASKELL__ >= 704
+import GHC.Generics
+#endif
 
 -- | The trivial monad transformer, which maps a monad to an equivalent monad.
 newtype IdentityT f a = IdentityT { runIdentityT :: f a }
+#if __GLASGOW_HASKELL__ >= 710
+    deriving (Generic, Generic1)
+#elif __GLASGOW_HASKELL__ >= 704
+    deriving (Generic)
+#endif
 
 instance (Eq1 f) => Eq1 (IdentityT f) where
     liftEq eq (IdentityT x) (IdentityT y) = liftEq eq x y
@@ -78,9 +96,27 @@
     {-# INLINE fmap #-}
 
 instance (Foldable f) => Foldable (IdentityT f) where
-    foldMap f (IdentityT a) = foldMap f a
+    foldMap f (IdentityT t) = foldMap f t
     {-# INLINE foldMap #-}
+    foldr f z (IdentityT t) = foldr f z t
+    {-# INLINE foldr #-}
+    foldl f z (IdentityT t) = foldl f z t
+    {-# INLINE foldl #-}
+    foldr1 f (IdentityT t) = foldr1 f t
+    {-# INLINE foldr1 #-}
+    foldl1 f (IdentityT t) = foldl1 f t
+    {-# INLINE foldl1 #-}
+#if MIN_VERSION_base(4,8,0)
+    null (IdentityT t) = null t
+    length (IdentityT t) = length t
+#endif
 
+#if MIN_VERSION_base(4,18,0)
+instance (Foldable1 m) => Foldable1 (IdentityT m) where
+    foldMap1 f (IdentityT t) = foldMap1 f t
+    {-# INLINE foldMap1 #-}
+#endif
+
 instance (Traversable f) => Traversable (IdentityT f) where
     traverse f (IdentityT a) = IdentityT <$> traverse f a
     {-# INLINE traverse #-}
@@ -90,6 +126,10 @@
     {-# INLINE pure #-}
     (<*>) = lift2IdentityT (<*>)
     {-# INLINE (<*>) #-}
+    (*>) = lift2IdentityT (*>)
+    {-# INLINE (*>) #-}
+    (<*) = lift2IdentityT (<*)
+    {-# INLINE (<*) #-}
 
 instance (Alternative m) => Alternative (IdentityT m) where
     empty = IdentityT empty
@@ -104,8 +144,10 @@
 #endif
     m >>= k = IdentityT $ runIdentityT . k =<< runIdentityT m
     {-# INLINE (>>=) #-}
+#if !(MIN_VERSION_base(4,13,0))
     fail msg = IdentityT $ fail msg
     {-# INLINE fail #-}
+#endif
 
 #if MIN_VERSION_base(4,9,0)
 instance (Fail.MonadFail m) => Fail.MonadFail (IdentityT m) where
@@ -136,6 +178,12 @@
 instance MonadTrans IdentityT where
     lift = IdentityT
     {-# INLINE lift #-}
+
+#if MIN_VERSION_base(4,12,0)
+instance (Contravariant f) => Contravariant (IdentityT f) where
+    contramap f = IdentityT . contramap f . runIdentityT
+    {-# INLINE contramap #-}
+#endif
 
 -- | Lift a unary operation to the new monad.
 mapIdentityT :: (m a -> n b) -> IdentityT m a -> IdentityT n b
diff --git a/Control/Monad/Trans/List.hs b/Control/Monad/Trans/List.hs
deleted file mode 100644
--- a/Control/Monad/Trans/List.hs
+++ /dev/null
@@ -1,166 +0,0 @@
-{-# LANGUAGE CPP #-}
-#if __GLASGOW_HASKELL__ >= 702
-{-# LANGUAGE Safe #-}
-#endif
-#if __GLASGOW_HASKELL__ >= 710
-{-# LANGUAGE AutoDeriveTypeable #-}
-#endif
------------------------------------------------------------------------------
--- |
--- Module      :  Control.Monad.Trans.List
--- Copyright   :  (c) Andy Gill 2001,
---                (c) Oregon Graduate Institute of Science and Technology, 2001
--- License     :  BSD-style (see the file LICENSE)
---
--- Maintainer  :  R.Paterson@city.ac.uk
--- Stability   :  experimental
--- Portability :  portable
---
--- The ListT monad transformer, adding backtracking to a given monad,
--- which must be commutative.
------------------------------------------------------------------------------
-
-module Control.Monad.Trans.List (
-    -- * The ListT monad transformer
-    ListT(..),
-    mapListT,
-    -- * Lifting other operations
-    liftCallCC,
-    liftCatch,
-  ) where
-
-import Control.Monad.IO.Class
-import Control.Monad.Signatures
-import Control.Monad.Trans.Class
-import Data.Functor.Classes
-
-import Control.Applicative
-import Control.Monad
-#if MIN_VERSION_base(4,9,0)
-import qualified Control.Monad.Fail as Fail
-#endif
-#if MIN_VERSION_base(4,4,0)
-import Control.Monad.Zip (MonadZip(mzipWith))
-#endif
-import Data.Foldable (Foldable(foldMap))
-import Data.Traversable (Traversable(traverse))
-
--- | Parameterizable list monad, with an inner monad.
---
--- /Note:/ this does not yield a monad unless the argument monad is commutative.
-newtype ListT m a = ListT { runListT :: m [a] }
-
-instance (Eq1 m) => Eq1 (ListT m) where
-    liftEq eq (ListT x) (ListT y) = liftEq (liftEq eq) x y
-    {-# INLINE liftEq #-}
-
-instance (Ord1 m) => Ord1 (ListT m) where
-    liftCompare comp (ListT x) (ListT y) = liftCompare (liftCompare comp) x y
-    {-# INLINE liftCompare #-}
-
-instance (Read1 m) => Read1 (ListT m) where
-    liftReadsPrec rp rl = readsData $
-        readsUnaryWith (liftReadsPrec rp' rl') "ListT" ListT
-      where
-        rp' = liftReadsPrec rp rl
-        rl' = liftReadList rp rl
-
-instance (Show1 m) => Show1 (ListT m) where
-    liftShowsPrec sp sl d (ListT m) =
-        showsUnaryWith (liftShowsPrec sp' sl') "ListT" d m
-      where
-        sp' = liftShowsPrec sp sl
-        sl' = liftShowList sp sl
-
-instance (Eq1 m, Eq a) => Eq (ListT m a) where (==) = eq1
-instance (Ord1 m, Ord a) => Ord (ListT m a) where compare = compare1
-instance (Read1 m, Read a) => Read (ListT m a) where readsPrec = readsPrec1
-instance (Show1 m, Show a) => Show (ListT m a) where showsPrec = showsPrec1
-
--- | Map between 'ListT' computations.
---
--- * @'runListT' ('mapListT' f m) = f ('runListT' m)@
-mapListT :: (m [a] -> n [b]) -> ListT m a -> ListT n b
-mapListT f m = ListT $ f (runListT m)
-{-# INLINE mapListT #-}
-
-instance (Functor m) => Functor (ListT m) where
-    fmap f = mapListT $ fmap $ map f
-    {-# INLINE fmap #-}
-
-instance (Foldable f) => Foldable (ListT f) where
-    foldMap f (ListT a) = foldMap (foldMap f) a
-    {-# INLINE foldMap #-}
-
-instance (Traversable f) => Traversable (ListT f) where
-    traverse f (ListT a) = ListT <$> traverse (traverse f) a
-    {-# INLINE traverse #-}
-
-instance (Applicative m) => Applicative (ListT m) where
-    pure a  = ListT $ pure [a]
-    {-# INLINE pure #-}
-    f <*> v = ListT $ (<*>) <$> runListT f <*> runListT v
-    {-# INLINE (<*>) #-}
-
-instance (Applicative m) => Alternative (ListT m) where
-    empty   = ListT $ pure []
-    {-# INLINE empty #-}
-    m <|> n = ListT $ (++) <$> runListT m <*> runListT n
-    {-# INLINE (<|>) #-}
-
-instance (Monad m) => Monad (ListT m) where
-#if !(MIN_VERSION_base(4,8,0))
-    return a = ListT $ return [a]
-    {-# INLINE return #-}
-#endif
-    m >>= k  = ListT $ do
-        a <- runListT m
-        b <- mapM (runListT . k) a
-        return (concat b)
-    {-# INLINE (>>=) #-}
-    fail _ = ListT $ return []
-    {-# INLINE fail #-}
-
-#if MIN_VERSION_base(4,9,0)
-instance (Monad m) => Fail.MonadFail (ListT m) where
-    fail _ = ListT $ return []
-    {-# INLINE fail #-}
-#endif
-
-instance (Monad m) => MonadPlus (ListT m) where
-    mzero       = ListT $ return []
-    {-# INLINE mzero #-}
-    m `mplus` n = ListT $ do
-        a <- runListT m
-        b <- runListT n
-        return (a ++ b)
-    {-# INLINE mplus #-}
-
-instance MonadTrans ListT where
-    lift m = ListT $ do
-        a <- m
-        return [a]
-    {-# INLINE lift #-}
-
-instance (MonadIO m) => MonadIO (ListT m) where
-    liftIO = lift . liftIO
-    {-# INLINE liftIO #-}
-
-#if MIN_VERSION_base(4,4,0)
-instance (MonadZip m) => MonadZip (ListT m) where
-    mzipWith f (ListT a) (ListT b) = ListT $ mzipWith (zipWith f) a b
-    {-# INLINE mzipWith #-}
-#endif
-
--- | Lift a @callCC@ operation to the new monad.
-liftCallCC :: CallCC m [a] [b] -> CallCC (ListT m) a b
-liftCallCC callCC f = ListT $
-    callCC $ \ c ->
-    runListT (f (\ a -> ListT $ c [a]))
-{-# INLINE liftCallCC #-}
-
--- | Lift a @catchE@ operation to the new monad.
-liftCatch :: Catch e m [a] -> Catch e (ListT m) a
-liftCatch catchE m h = ListT $ runListT m
-    `catchE` \ e -> runListT (h e)
-{-# INLINE liftCatch #-}
diff --git a/Control/Monad/Trans/Maybe.hs b/Control/Monad/Trans/Maybe.hs
--- a/Control/Monad/Trans/Maybe.hs
+++ b/Control/Monad/Trans/Maybe.hs
@@ -1,8 +1,9 @@
 {-# LANGUAGE CPP #-}
 #if __GLASGOW_HASKELL__ >= 702
 {-# LANGUAGE Safe #-}
+{-# LANGUAGE DeriveGeneric #-}
 #endif
-#if __GLASGOW_HASKELL__ >= 710
+#if __GLASGOW_HASKELL__ >= 710 && __GLASGOW_HASKELL__ < 802
 {-# LANGUAGE AutoDeriveTypeable #-}
 #endif
 -----------------------------------------------------------------------------
@@ -30,7 +31,8 @@
     -- * The MaybeT monad transformer
     MaybeT(..),
     mapMaybeT,
-    -- * Conversion
+    -- * Monad transformations
+    hoistMaybe,
     maybeToExceptT,
     exceptToMaybeT,
     -- * Lifting other operations
@@ -45,6 +47,9 @@
 import Control.Monad.Trans.Class
 import Control.Monad.Trans.Except (ExceptT(..))
 import Data.Functor.Classes
+#if MIN_VERSION_base(4,12,0)
+import Data.Functor.Contravariant
+#endif
 
 import Control.Applicative
 import Control.Monad (MonadPlus(mzero, mplus), liftM)
@@ -55,12 +60,17 @@
 #if MIN_VERSION_base(4,4,0)
 import Control.Monad.Zip (MonadZip(mzipWith))
 #endif
-import Data.Foldable (Foldable(foldMap))
 import Data.Maybe (fromMaybe)
+#if !(MIN_VERSION_base(4,8,0)) || defined(__MHS__)
+import Data.Foldable (Foldable(foldMap))
 import Data.Traversable (Traversable(traverse))
+#endif
+#if __GLASGOW_HASKELL__ >= 704
+import GHC.Generics
+#endif
 
--- | The parameterizable maybe monad, obtained by composing an arbitrary
--- monad with the 'Maybe' monad.
+-- | The parameterizable maybe monad, a strict monad obtained by composing
+-- an arbitrary monad with the 'Maybe' monad.
 --
 -- Computations are actions that may produce a value or exit.
 --
@@ -68,6 +78,11 @@
 -- value, while @>>=@ sequences two subcomputations, exiting if either
 -- computation does.
 newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) }
+#if __GLASGOW_HASKELL__ >= 710
+    deriving (Generic, Generic1)
+#elif __GLASGOW_HASKELL__ >= 704
+    deriving (Generic)
+#endif
 
 instance (Eq1 m) => Eq1 (MaybeT m) where
     liftEq eq (MaybeT x) (MaybeT y) = liftEq (liftEq eq) x y
@@ -103,6 +118,10 @@
 mapMaybeT f = MaybeT . f . runMaybeT
 {-# INLINE mapMaybeT #-}
 
+-- | Convert a 'Maybe' computation to 'MaybeT'.
+hoistMaybe :: (Applicative m) => Maybe b -> MaybeT m b
+hoistMaybe = MaybeT . pure
+
 -- | Convert a 'MaybeT' computation to 'ExceptT', with a default
 -- exception value.
 maybeToExceptT :: (Functor m) => e -> MaybeT m a -> ExceptT e m a
@@ -128,7 +147,7 @@
     {-# INLINE traverse #-}
 
 instance (Functor m, Monad m) => Applicative (MaybeT m) where
-    pure = lift . return
+    pure = MaybeT . return . Just
     {-# INLINE pure #-}
     mf <*> mx = MaybeT $ do
         mb_f <- runMaybeT mf
@@ -140,6 +159,8 @@
                     Nothing -> return Nothing
                     Just x  -> return (Just (f x))
     {-# INLINE (<*>) #-}
+    m *> k = m >>= \_ -> k
+    {-# INLINE (*>) #-}
 
 instance (Functor m, Monad m) => Alternative (MaybeT m) where
     empty = MaybeT (return Nothing)
@@ -153,7 +174,7 @@
 
 instance (Monad m) => Monad (MaybeT m) where
 #if !(MIN_VERSION_base(4,8,0))
-    return = lift . return
+    return = MaybeT . return . Just
     {-# INLINE return #-}
 #endif
     x >>= f = MaybeT $ do
@@ -162,8 +183,10 @@
             Nothing -> return Nothing
             Just y  -> runMaybeT (f y)
     {-# INLINE (>>=) #-}
+#if !(MIN_VERSION_base(4,13,0))
     fail _ = MaybeT (return Nothing)
     {-# INLINE fail #-}
+#endif
 
 #if MIN_VERSION_base(4,9,0)
 instance (Monad m) => Fail.MonadFail (MaybeT m) where
@@ -198,6 +221,12 @@
 instance (MonadZip m) => MonadZip (MaybeT m) where
     mzipWith f (MaybeT a) (MaybeT b) = MaybeT $ mzipWith (liftA2 f) a b
     {-# INLINE mzipWith #-}
+#endif
+
+#if MIN_VERSION_base(4,12,0)
+instance Contravariant m => Contravariant (MaybeT m) where
+    contramap f = MaybeT . contramap (fmap f) . runMaybeT
+    {-# INLINE contramap #-}
 #endif
 
 -- | Lift a @callCC@ operation to the new monad.
diff --git a/Control/Monad/Trans/RWS.hs b/Control/Monad/Trans/RWS.hs
--- a/Control/Monad/Trans/RWS.hs
+++ b/Control/Monad/Trans/RWS.hs
@@ -13,9 +13,11 @@
 -- Stability   :  experimental
 -- Portability :  portable
 --
--- A monad transformer that combines 'ReaderT', 'WriterT' and 'StateT'.
--- This version is lazy; for a strict version, see
--- "Control.Monad.Trans.RWS.Strict", which has the same interface.
+-- A monad transformer that combines 'Control.Monad.Trans.Reader.ReaderT',
+-- 'Control.Monad.Trans.Writer.Lazy.WriterT' and
+-- 'Control.Monad.Trans.State.Lazy.StateT'.
+-- This version is lazy; for a constant-space version with almost the
+-- same interface, see "Control.Monad.Trans.RWS.CPS".
 -----------------------------------------------------------------------------
 
 module Control.Monad.Trans.RWS (
diff --git a/Control/Monad/Trans/RWS/CPS.hs b/Control/Monad/Trans/RWS/CPS.hs
new file mode 100644
--- /dev/null
+++ b/Control/Monad/Trans/RWS/CPS.hs
@@ -0,0 +1,418 @@
+{-# LANGUAGE CPP #-}
+#if __GLASGOW_HASKELL__ >= 702
+{-# LANGUAGE Safe #-}
+{-# LANGUAGE DeriveGeneric #-}
+#endif
+#if __GLASGOW_HASKELL__ >= 710 && __GLASGOW_HASKELL__ < 802
+{-# LANGUAGE AutoDeriveTypeable #-}
+#endif
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Control.Monad.Trans.RWS.CPS
+-- Copyright   :  (c) Daniel Mendler 2016,
+--                (c) Andy Gill 2001,
+--                (c) Oregon Graduate Institute of Science and Technology, 2001
+-- License     :  BSD-style (see the file LICENSE)
+--
+-- Maintainer  :  R.Paterson@city.ac.uk
+-- Stability   :  experimental
+-- Portability :  portable
+--
+-- A monad transformer that combines 'Control.Monad.Trans.Reader.ReaderT',
+-- 'Control.Monad.Trans.Writer.CPS.WriterT' and
+-- 'Control.Monad.Trans.State.Strict.StateT'.
+-- This version uses continuation-passing-style for the writer part
+-- to achieve constant space usage.
+-- For a lazy version with the same interface,
+-- see "Control.Monad.Trans.RWS.Lazy".
+-----------------------------------------------------------------------------
+
+module Control.Monad.Trans.RWS.CPS (
+    -- * The RWS monad
+    RWS,
+    rws,
+    runRWS,
+    evalRWS,
+    execRWS,
+    mapRWS,
+    withRWS,
+    -- * The RWST monad transformer
+    RWST,
+    rwsT,
+    runRWST,
+    evalRWST,
+    execRWST,
+    mapRWST,
+    withRWST,
+    -- * Reader operations
+    reader,
+    ask,
+    local,
+    asks,
+    -- * Writer operations
+    writer,
+    tell,
+    listen,
+    listens,
+    pass,
+    censor,
+    -- * State operations
+    state,
+    get,
+    put,
+    modify,
+    gets,
+    -- * Lifting other operations
+    liftCallCC,
+    liftCallCC',
+    liftCatch,
+  ) where
+
+import Control.Applicative
+import Control.Monad
+import Control.Monad.Fix
+import Control.Monad.IO.Class
+import Control.Monad.Trans.Class
+import Control.Monad.Signatures
+import Data.Functor.Identity
+
+#if !(MIN_VERSION_base(4,8,0))
+import Data.Monoid
+#endif
+
+#if MIN_VERSION_base(4,9,0)
+import qualified Control.Monad.Fail as Fail
+#endif
+#if __GLASGOW_HASKELL__ >= 704
+import GHC.Generics
+#endif
+
+-- | A monad containing an environment of type @r@, output of type @w@
+-- and an updatable state of type @s@.
+type RWS r w s = RWST r w s Identity
+
+-- | Construct an RWS computation from a function.
+-- (The inverse of 'runRWS'.)
+rws :: (Monoid w) => (r -> s -> (a, s, w)) -> RWS r w s a
+rws f = RWST $ \ r s w ->
+    let (a, s', w') = f r s; wt = w `mappend` w' in wt `seq` return (a, s', wt)
+{-# INLINE rws #-}
+
+-- | Unwrap an RWS computation as a function.
+-- (The inverse of 'rws'.)
+runRWS :: (Monoid w) => RWS r w s a -> r -> s -> (a, s, w)
+runRWS m r s = runIdentity (runRWST m r s)
+{-# INLINE runRWS #-}
+
+-- | Evaluate a computation with the given initial state and environment,
+-- returning the final value and output, discarding the final state.
+evalRWS :: (Monoid w)
+        => RWS r w s a  -- ^RWS computation to execute
+        -> r            -- ^initial environment
+        -> s            -- ^initial value
+        -> (a, w)       -- ^final value and output
+evalRWS m r s = let
+    (a, _, w) = runRWS m r s
+    in (a, w)
+{-# INLINE evalRWS #-}
+
+-- | Evaluate a computation with the given initial state and environment,
+-- returning the final state and output, discarding the final value.
+execRWS :: (Monoid w)
+        => RWS r w s a  -- ^RWS computation to execute
+        -> r            -- ^initial environment
+        -> s            -- ^initial value
+        -> (s, w)       -- ^final state and output
+execRWS m r s = let
+    (_, s', w) = runRWS m r s
+    in (s', w)
+{-# INLINE execRWS #-}
+
+-- | Map the return value, final state and output of a computation using
+-- the given function.
+--
+-- * @'runRWS' ('mapRWS' f m) r s = f ('runRWS' m r s)@
+mapRWS :: (Monoid w, Monoid w') => ((a, s, w) -> (b, s, w')) -> RWS r w s a -> RWS r w' s b
+mapRWS f = mapRWST (Identity . f . runIdentity)
+{-# INLINE mapRWS #-}
+
+-- | @'withRWS' f m@ executes action @m@ with an initial environment
+-- and state modified by applying @f@.
+--
+-- * @'runRWS' ('withRWS' f m) r s = 'uncurry' ('runRWS' m) (f r s)@
+withRWS :: (r' -> s -> (r, s)) -> RWS r w s a -> RWS r' w s a
+withRWS = withRWST
+{-# INLINE withRWS #-}
+
+-- ---------------------------------------------------------------------------
+-- | A monad transformer adding reading an environment of type @r@,
+-- collecting an output of type @w@ and updating a state of type @s@
+-- to an inner monad @m@.
+newtype RWST r w s m a = RWST { unRWST :: r -> s -> w -> m (a, s, w) }
+#if __GLASGOW_HASKELL__ >= 704
+    deriving (Generic)
+#endif
+
+-- | Construct an RWST computation from a function.
+-- (The inverse of 'runRWST'.)
+rwsT :: (Functor m, Monoid w) => (r -> s -> m (a, s, w)) -> RWST r w s m a
+rwsT f = RWST $ \ r s w ->
+     (\ (a, s', w') -> let wt = w `mappend` w' in wt `seq` (a, s', wt)) <$> f r s
+{-# INLINE rwsT #-}
+
+-- | Unwrap an RWST computation as a function.
+-- (The inverse of 'rwsT'.)
+runRWST :: (Monoid w) => RWST r w s m a -> r -> s -> m (a, s, w)
+runRWST m r s = unRWST m r s mempty
+{-# INLINE runRWST #-}
+
+-- | Evaluate a computation with the given initial state and environment,
+-- returning the final value and output, discarding the final state.
+evalRWST :: (Monad m, Monoid w)
+         => RWST r w s m a      -- ^computation to execute
+         -> r                   -- ^initial environment
+         -> s                   -- ^initial value
+         -> m (a, w)            -- ^computation yielding final value and output
+evalRWST m r s = do
+    (a, _, w) <- runRWST m r s
+    return (a, w)
+{-# INLINE evalRWST #-}
+
+-- | Evaluate a computation with the given initial state and environment,
+-- returning the final state and output, discarding the final value.
+execRWST :: (Monad m, Monoid w)
+         => RWST r w s m a      -- ^computation to execute
+         -> r                   -- ^initial environment
+         -> s                   -- ^initial value
+         -> m (s, w)            -- ^computation yielding final state and output
+execRWST m r s = do
+    (_, s', w) <- runRWST m r s
+    return (s', w)
+{-# INLINE execRWST #-}
+
+-- | Map the inner computation using the given function.
+--
+-- * @'runRWST' ('mapRWST' f m) r s = f ('runRWST' m r s)@
+--mapRWST :: (m (a, s, w) -> n (b, s, w')) -> RWST r w s m a -> RWST r w' s n b
+mapRWST :: (Monad n, Monoid w, Monoid w') =>
+    (m (a, s, w) -> n (b, s, w')) -> RWST r w s m a -> RWST r w' s n b
+mapRWST f m = RWST $ \ r s w -> do
+    (a, s', w') <- f (runRWST m r s)
+    let wt = w `mappend` w'
+    wt `seq` return (a, s', wt)
+{-# INLINE mapRWST #-}
+
+-- | @'withRWST' f m@ executes action @m@ with an initial environment
+-- and state modified by applying @f@.
+--
+-- * @'runRWST' ('withRWST' f m) r s = 'uncurry' ('runRWST' m) (f r s)@
+withRWST :: (r' -> s -> (r, s)) -> RWST r w s m a -> RWST r' w s m a
+withRWST f m = RWST $ \ r s -> uncurry (unRWST m) (f r s)
+{-# INLINE withRWST #-}
+
+instance (Functor m) => Functor (RWST r w s m) where
+    fmap f m = RWST $ \ r s w -> (\ (a, s', w') -> (f a, s', w')) <$> unRWST m r s w
+    {-# INLINE fmap #-}
+
+instance (Functor m, Monad m) => Applicative (RWST r w s m) where
+    pure a = RWST $ \ _ s w -> return (a, s, w)
+    {-# INLINE pure #-}
+
+    RWST mf <*> RWST mx = RWST $ \ r s w -> do
+        (f, s', w')    <- mf r s w
+        (x, s'', w'') <- mx r s' w'
+        return (f x, s'', w'')
+    {-# INLINE (<*>) #-}
+
+instance (Functor m, MonadPlus m) => Alternative (RWST r w s m) where
+    empty = RWST $ \ _ _ _ -> mzero
+    {-# INLINE empty #-}
+
+    RWST m <|> RWST n = RWST $ \ r s w -> m r s w `mplus` n r s w
+    {-# INLINE (<|>) #-}
+
+instance (Monad m) => Monad (RWST r w s m) where
+#if !(MIN_VERSION_base(4,8,0))
+    return a = RWST $ \ _ s w -> return (a, s, w)
+    {-# INLINE return #-}
+#endif
+
+    m >>= k = RWST $ \ r s w -> do
+        (a, s', w')    <- unRWST m r s w
+        unRWST (k a) r s' w'
+    {-# INLINE (>>=) #-}
+
+#if !(MIN_VERSION_base(4,13,0))
+    fail msg = RWST $ \ _ _ _ -> fail msg
+    {-# INLINE fail #-}
+#endif
+
+#if MIN_VERSION_base(4,9,0)
+instance (Fail.MonadFail m) => Fail.MonadFail (RWST r w s m) where
+    fail msg = RWST $ \ _ _ _ -> Fail.fail msg
+    {-# INLINE fail #-}
+#endif
+
+instance (Functor m, MonadPlus m) => MonadPlus (RWST r w s m) where
+    mzero = empty
+    {-# INLINE mzero #-}
+    mplus = (<|>)
+    {-# INLINE mplus #-}
+
+instance (MonadFix m) => MonadFix (RWST r w s m) where
+    mfix f = RWST $ \ r s w -> mfix $ \ ~(a, _, _) -> unRWST (f a) r s w
+    {-# INLINE mfix #-}
+
+instance MonadTrans (RWST r w s) where
+    lift m = RWST $ \ _ s w -> do
+        a <- m
+        return (a, s, w)
+    {-# INLINE lift #-}
+
+instance (MonadIO m) => MonadIO (RWST r w s m) where
+    liftIO = lift . liftIO
+    {-# INLINE liftIO #-}
+-- ---------------------------------------------------------------------------
+-- Reader operations
+
+-- | Constructor for computations in the reader monad (equivalent to 'asks').
+reader :: (Monad m) => (r -> a) -> RWST r w s m a
+reader = asks
+{-# INLINE reader #-}
+
+-- | Fetch the value of the environment.
+ask :: (Monad m) => RWST r w s m r
+ask = asks id
+{-# INLINE ask #-}
+
+-- | Execute a computation in a modified environment
+--
+-- * @'runRWST' ('local' f m) r s = 'runRWST' m (f r) s@
+local :: (r -> r) -> RWST r w s m a -> RWST r w s m a
+local f m = RWST $ \ r s w -> unRWST m (f r) s w
+{-# INLINE local #-}
+
+-- | Retrieve a function of the current environment.
+--
+-- * @'asks' f = 'liftM' f 'ask'@
+asks :: (Monad m) => (r -> a) -> RWST r w s m a
+asks f = RWST $ \ r s w -> return (f r, s, w)
+{-# INLINE asks #-}
+
+-- ---------------------------------------------------------------------------
+-- Writer operations
+
+-- | Construct a writer computation from a (result, output) pair.
+writer :: (Monoid w, Monad m) => (a, w) -> RWST r w s m a
+writer (a, w') = RWST $ \ _ s w -> let wt = w `mappend` w' in wt `seq` return (a, s, wt)
+{-# INLINE writer #-}
+
+-- | @'tell' w@ is an action that produces the output @w@.
+tell :: (Monoid w, Monad m) => w -> RWST r w s m ()
+tell w' = writer ((), w')
+{-# INLINE tell #-}
+
+-- | @'listen' m@ is an action that executes the action @m@ and adds its
+-- output to the value of the computation.
+--
+-- * @'runRWST' ('listen' m) r s = 'liftM' (\\ (a, w) -> ((a, w), w)) ('runRWST' m r s)@
+listen :: (Monoid w, Monad m) => RWST r w s m a -> RWST r w s m (a, w)
+listen = listens id
+{-# INLINE listen #-}
+
+-- | @'listens' f m@ is an action that executes the action @m@ and adds
+-- the result of applying @f@ to the output to the value of the computation.
+--
+-- * @'listens' f m = 'liftM' (id *** f) ('listen' m)@
+--
+-- * @'runRWST' ('listens' f m) r s = 'liftM' (\\ (a, w) -> ((a, f w), w)) ('runRWST' m r s)@
+listens :: (Monoid w, Monad m) => (w -> b) -> RWST r w s m a -> RWST r w s m (a, b)
+listens f m = RWST $ \ r s w -> do
+    (a, s', w') <- runRWST m r s
+    let wt = w `mappend` w'
+    wt `seq` return ((a, f w'), s', wt)
+{-# INLINE listens #-}
+
+-- | @'pass' m@ is an action that executes the action @m@, which returns
+-- a value and a function, and returns the value, applying the function
+-- to the output.
+--
+-- * @'runRWST' ('pass' m) r s = 'liftM' (\\ ((a, f), w) -> (a, f w)) ('runRWST' m r s)@
+pass :: (Monoid w, Monoid w', Monad m) => RWST r w s m (a, w -> w') -> RWST r w' s m a
+pass m = RWST $ \ r s w -> do
+    ((a, f), s', w') <- runRWST m r s
+    let wt = w `mappend` f w'
+    wt `seq` return (a, s', wt)
+{-# INLINE pass #-}
+
+-- | @'censor' f m@ is an action that executes the action @m@ and
+-- applies the function @f@ to its output, leaving the return value
+-- unchanged.
+--
+-- * @'censor' f m = 'pass' ('liftM' (\\ x -> (x,f)) m)@
+--
+-- * @'runRWST' ('censor' f m) r s = 'liftM' (\\ (a, w) -> (a, f w)) ('runRWST' m r s)@
+censor :: (Monoid w, Monad m) => (w -> w) -> RWST r w s m a -> RWST r w s m a
+censor f m = RWST $ \ r s w -> do
+    (a, s', w') <- runRWST m r s
+    let wt = w `mappend` f w'
+    wt `seq` return (a, s', wt)
+{-# INLINE censor #-}
+
+-- ---------------------------------------------------------------------------
+-- State operations
+
+-- | Construct a state monad computation from a state transformer function.
+state :: (Monad m) => (s -> (a, s)) -> RWST r w s m a
+state f = RWST $ \ _ s w -> let (a, s') = f s in return (a, s', w)
+{-# INLINE state #-}
+
+-- | Fetch the current value of the state within the monad.
+get :: (Monad m) =>RWST r w s m s
+get = gets id
+{-# INLINE get #-}
+
+-- | @'put' s@ sets the state within the monad to @s@.
+put :: (Monad m) =>s -> RWST r w s m ()
+put s = RWST $ \ _ _ w -> return ((), s, w)
+{-# INLINE put #-}
+
+-- | @'modify' f@ is an action that updates the state to the result of
+-- applying @f@ to the current state.
+--
+-- * @'modify' f = 'get' >>= ('put' . f)@
+modify :: (Monad m) =>(s -> s) -> RWST r w s m ()
+modify f = RWST $ \ _ s w -> return ((), f s, w)
+{-# INLINE modify #-}
+
+-- | Get a specific component of the state, using a projection function
+-- supplied.
+--
+-- * @'gets' f = 'liftM' f 'get'@
+gets :: (Monad m) =>(s -> a) -> RWST r w s m a
+gets f = RWST $ \ _ s w -> return (f s, s, w)
+{-# INLINE gets #-}
+
+-- | Uniform lifting of a @callCC@ operation to the new monad.
+-- This version rolls back to the original state on entering the
+-- continuation.
+liftCallCC :: CallCC m (a,s,w) (b,s,w) -> CallCC (RWST r w s m) a b
+liftCallCC callCC f = RWST $ \ r s w ->
+    callCC $ \ c -> unRWST (f (\ a -> RWST $ \ _ _ _ -> c (a, s, w))) r s w
+{-# INLINE liftCallCC #-}
+
+-- | In-situ lifting of a @callCC@ operation to the new monad.
+-- This version uses the current state on entering the continuation.
+liftCallCC' :: CallCC m (a,s,w) (b,s,w) -> CallCC (RWST r w s m) a b
+liftCallCC' callCC f = RWST $ \ r s w ->
+    callCC $ \ c -> unRWST (f (\ a -> RWST $ \ _ s' _ -> c (a, s', w))) r s w
+{-# INLINE liftCallCC' #-}
+
+-- | Lift a @catchE@ operation to the new monad.
+-- The uniformity property (see "Control.Monad.Signatures") implies that
+-- the lifted @catchE@ discards any output or changes to the state from
+-- the body on entering the handler.
+liftCatch :: Catch e m (a,s,w) -> Catch e (RWST r w s m) a
+liftCatch catchE m h =
+    RWST $ \ r s w -> unRWST m r s w `catchE` \ e -> unRWST (h e) r s w
+{-# INLINE liftCatch #-}
diff --git a/Control/Monad/Trans/RWS/Lazy.hs b/Control/Monad/Trans/RWS/Lazy.hs
--- a/Control/Monad/Trans/RWS/Lazy.hs
+++ b/Control/Monad/Trans/RWS/Lazy.hs
@@ -1,8 +1,9 @@
 {-# LANGUAGE CPP #-}
 #if __GLASGOW_HASKELL__ >= 702
 {-# LANGUAGE Safe #-}
+{-# LANGUAGE DeriveGeneric #-}
 #endif
-#if __GLASGOW_HASKELL__ >= 710
+#if __GLASGOW_HASKELL__ >= 710 && __GLASGOW_HASKELL__ < 802
 {-# LANGUAGE AutoDeriveTypeable #-}
 #endif
 -----------------------------------------------------------------------------
@@ -16,9 +17,11 @@
 -- Stability   :  experimental
 -- Portability :  portable
 --
--- A monad transformer that combines 'ReaderT', 'WriterT' and 'StateT'.
--- This version is lazy; for a strict version with the same interface,
--- see "Control.Monad.Trans.RWS.Strict".
+-- A monad transformer that combines 'Control.Monad.Trans.Reader.ReaderT',
+-- 'Control.Monad.Trans.Writer.Lazy.WriterT' and
+-- 'Control.Monad.Trans.State.Lazy.StateT'.
+-- This version is lazy; for a constant-space version with almost the
+-- same interface, see "Control.Monad.Trans.RWS.CPS".
 -----------------------------------------------------------------------------
 
 module Control.Monad.Trans.RWS.Lazy (
@@ -63,6 +66,9 @@
 import Control.Monad.IO.Class
 import Control.Monad.Signatures
 import Control.Monad.Trans.Class
+#if MIN_VERSION_base(4,12,0)
+import Data.Functor.Contravariant
+#endif
 import Data.Functor.Identity
 
 import Control.Applicative
@@ -71,7 +77,12 @@
 import qualified Control.Monad.Fail as Fail
 #endif
 import Control.Monad.Fix
+#if !(MIN_VERSION_base(4,8,0))
 import Data.Monoid
+#endif
+#if __GLASGOW_HASKELL__ >= 704
+import GHC.Generics
+#endif
 
 -- | A monad containing an environment of type @r@, output of type @w@
 -- and an updatable state of type @s@.
@@ -132,7 +143,9 @@
 -- collecting an output of type @w@ and updating a state of type @s@
 -- to an inner monad @m@.
 newtype RWST r w s m a = RWST { runRWST :: r -> s -> m (a, s, w) }
-
+#if __GLASGOW_HASKELL__ >= 704
+    deriving (Generic)
+#endif
 -- | Evaluate a computation with the given initial state and environment,
 -- returning the final value and output, discarding the final state.
 evalRWST :: (Monad m)
@@ -202,8 +215,10 @@
         ~(b, s'',w') <- runRWST (k a) r s'
         return (b, s'', w `mappend` w')
     {-# INLINE (>>=) #-}
+#if !(MIN_VERSION_base(4,13,0))
     fail msg = RWST $ \ _ _ -> fail msg
     {-# INLINE fail #-}
+#endif
 
 #if MIN_VERSION_base(4,9,0)
 instance (Monoid w, Fail.MonadFail m) => Fail.MonadFail (RWST r w s m) where
@@ -231,6 +246,13 @@
     liftIO = lift . liftIO
     {-# INLINE liftIO #-}
 
+#if MIN_VERSION_base(4,12,0)
+instance Contravariant m => Contravariant (RWST r w s m) where
+    contramap f m = RWST $ \r s ->
+      contramap (\ ~(a, s', w) -> (f a, s', w)) $ runRWST m r s
+    {-# INLINE contramap #-}
+#endif
+
 -- ---------------------------------------------------------------------------
 -- Reader operations
 
@@ -371,6 +393,9 @@
 {-# INLINE liftCallCC' #-}
 
 -- | Lift a @catchE@ operation to the new monad.
+-- The uniformity property (see "Control.Monad.Signatures") implies that
+-- the lifted @catchE@ discards any output or changes to the state from
+-- the body on entering the handler.
 liftCatch :: Catch e m (a,s,w) -> Catch e (RWST r w s m) a
 liftCatch catchE m h =
     RWST $ \ r s -> runRWST m r s `catchE` \ e -> runRWST (h e) r s
diff --git a/Control/Monad/Trans/RWS/Strict.hs b/Control/Monad/Trans/RWS/Strict.hs
--- a/Control/Monad/Trans/RWS/Strict.hs
+++ b/Control/Monad/Trans/RWS/Strict.hs
@@ -1,8 +1,9 @@
 {-# LANGUAGE CPP #-}
 #if __GLASGOW_HASKELL__ >= 702
 {-# LANGUAGE Safe #-}
+{-# LANGUAGE DeriveGeneric #-}
 #endif
-#if __GLASGOW_HASKELL__ >= 710
+#if __GLASGOW_HASKELL__ >= 710 && __GLASGOW_HASKELL__ < 802
 {-# LANGUAGE AutoDeriveTypeable #-}
 #endif
 -----------------------------------------------------------------------------
@@ -16,9 +17,14 @@
 -- Stability   :  experimental
 -- Portability :  portable
 --
--- A monad transformer that combines 'ReaderT', 'WriterT' and 'StateT'.
+-- A monad transformer that combines 'Control.Monad.Trans.Reader.ReaderT',
+-- 'Control.Monad.Trans.Writer.Strict.WriterT' and
+-- 'Control.Monad.Trans.State.Strict.StateT'.
 -- This version is strict; for a lazy version with the same interface,
 -- see "Control.Monad.Trans.RWS.Lazy".
+-- Although the output is built strictly, it is not possible to
+-- achieve constant space behaviour with this transformer: for that,
+-- use "Control.Monad.Trans.RWS.CPS" instead.
 -----------------------------------------------------------------------------
 
 module Control.Monad.Trans.RWS.Strict (
@@ -63,6 +69,9 @@
 import Control.Monad.IO.Class
 import Control.Monad.Signatures
 import Control.Monad.Trans.Class
+#if MIN_VERSION_base(4,12,0)
+import Data.Functor.Contravariant
+#endif
 import Data.Functor.Identity
 
 import Control.Applicative
@@ -71,7 +80,12 @@
 import qualified Control.Monad.Fail as Fail
 #endif
 import Control.Monad.Fix
+#if !(MIN_VERSION_base(4,8,0))
 import Data.Monoid
+#endif
+#if __GLASGOW_HASKELL__ >= 704
+import GHC.Generics
+#endif
 
 -- | A monad containing an environment of type @r@, output of type @w@
 -- and an updatable state of type @s@.
@@ -132,6 +146,9 @@
 -- collecting an output of type @w@ and updating a state of type @s@
 -- to an inner monad @m@.
 newtype RWST r w s m a = RWST { runRWST :: r -> s -> m (a, s, w) }
+#if __GLASGOW_HASKELL__ >= 704
+    deriving (Generic)
+#endif
 
 -- | Evaluate a computation with the given initial state and environment,
 -- returning the final value and output, discarding the final state.
@@ -202,8 +219,10 @@
         (b, s'',w') <- runRWST (k a) r s'
         return (b, s'', w `mappend` w')
     {-# INLINE (>>=) #-}
+#if !(MIN_VERSION_base(4,13,0))
     fail msg = RWST $ \ _ _ -> fail msg
     {-# INLINE fail #-}
+#endif
 
 #if MIN_VERSION_base(4,9,0)
 instance (Monoid w, Fail.MonadFail m) => Fail.MonadFail (RWST r w s m) where
@@ -231,6 +250,13 @@
     liftIO = lift . liftIO
     {-# INLINE liftIO #-}
 
+#if MIN_VERSION_base(4,12,0)
+instance Contravariant m => Contravariant (RWST r w s m) where
+    contramap f m = RWST $ \r s ->
+      contramap (\ (a, s', w) -> (f a, s', w)) $ runRWST m r s
+    {-# INLINE contramap #-}
+#endif
+
 -- ---------------------------------------------------------------------------
 -- Reader operations
 
@@ -371,6 +397,9 @@
 {-# INLINE liftCallCC' #-}
 
 -- | Lift a @catchE@ operation to the new monad.
+-- The uniformity property (see "Control.Monad.Signatures") implies that
+-- the lifted @catchE@ discards any output or changes to the state from
+-- the body on entering the handler.
 liftCatch :: Catch e m (a,s,w) -> Catch e (RWST r w s m) a
 liftCatch catchE m h =
     RWST $ \ r s -> runRWST m r s `catchE` \ e -> runRWST (h e) r s
diff --git a/Control/Monad/Trans/Reader.hs b/Control/Monad/Trans/Reader.hs
--- a/Control/Monad/Trans/Reader.hs
+++ b/Control/Monad/Trans/Reader.hs
@@ -1,11 +1,9 @@
 {-# LANGUAGE CPP #-}
 #if __GLASGOW_HASKELL__ >= 702
 {-# LANGUAGE Safe #-}
-#endif
-#if __GLASGOW_HASKELL__ >= 706
-{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE DeriveGeneric #-}
 #endif
-#if __GLASGOW_HASKELL__ >= 710
+#if __GLASGOW_HASKELL__ >= 710 && __GLASGOW_HASKELL__ < 802
 {-# LANGUAGE AutoDeriveTypeable #-}
 #endif
 -----------------------------------------------------------------------------
@@ -49,6 +47,9 @@
 import Control.Monad.IO.Class
 import Control.Monad.Signatures
 import Control.Monad.Trans.Class
+#if MIN_VERSION_base(4,12,0)
+import Data.Functor.Contravariant
+#endif
 import Data.Functor.Identity
 
 import Control.Applicative
@@ -63,13 +64,22 @@
 #if MIN_VERSION_base(4,4,0)
 import Control.Monad.Zip (MonadZip(mzipWith))
 #endif
+#if (MIN_VERSION_base(4,2,0)) && !(MIN_VERSION_base(4,8,0))
+import Data.Functor ((<$))
+#endif
+#if __GLASGOW_HASKELL__ >= 704
+import GHC.Generics
+#endif
 
--- | The parameterizable reader monad.
+-- | The parameterizable reader monad, which is non-strict.
 --
 -- Computations are functions of a shared environment.
 --
--- The 'return' function ignores the environment, while @>>=@ passes
--- the inherited environment to both subcomputations.
+-- The 'return' function ignores the environment, while @m '>>=' k@
+-- passes the inherited environment to both subcomputations:
+--
+-- <<images/bind-ReaderT.svg>>
+--
 type Reader r = ReaderT r Identity
 
 -- | Constructor for computations in the reader monad (equivalent to 'asks').
@@ -107,9 +117,19 @@
 -- | The reader monad transformer,
 -- which adds a read-only environment to the given monad.
 --
--- The 'return' function ignores the environment, while @>>=@ passes
--- the inherited environment to both subcomputations.
+-- The 'return' function ignores the environment, while @m '>>=' k@
+-- passes the inherited environment to both subcomputations:
+--
+-- <<images/bind-ReaderT.svg>>
+--
+--
+-- @ReaderT r m@ is strict if and only if @m@ is.
 newtype ReaderT r m a = ReaderT { runReaderT :: r -> m a }
+#if __GLASGOW_HASKELL__ >= 710
+    deriving (Generic, Generic1)
+#elif __GLASGOW_HASKELL__ >= 704
+    deriving (Generic)
+#endif
 
 -- | Transform the computation inside a @ReaderT@.
 --
@@ -132,12 +152,26 @@
 instance (Functor m) => Functor (ReaderT r m) where
     fmap f  = mapReaderT (fmap f)
     {-# INLINE fmap #-}
+#if MIN_VERSION_base(4,2,0)
+    x <$ v = mapReaderT (x <$) v
+    {-# INLINE (<$) #-}
+#endif
 
 instance (Applicative m) => Applicative (ReaderT r m) where
     pure    = liftReaderT . pure
     {-# INLINE pure #-}
     f <*> v = ReaderT $ \ r -> runReaderT f r <*> runReaderT v r
     {-# INLINE (<*>) #-}
+#if MIN_VERSION_base(4,2,0)
+    u *> v = ReaderT $ \ r -> runReaderT u r *> runReaderT v r
+    {-# INLINE (*>) #-}
+    u <* v = ReaderT $ \ r -> runReaderT u r <* runReaderT v r
+    {-# INLINE (<*) #-}
+#endif
+#if MIN_VERSION_base(4,10,0)
+    liftA2 f x y = ReaderT $ \ r -> liftA2 f (runReaderT x r) (runReaderT y r)
+    {-# INLINE liftA2 #-}
+#endif
 
 instance (Alternative m) => Alternative (ReaderT r m) where
     empty   = liftReaderT empty
@@ -154,8 +188,16 @@
         a <- runReaderT m r
         runReaderT (k a) r
     {-# INLINE (>>=) #-}
+#if MIN_VERSION_base(4,8,0)
+    (>>) = (*>)
+#else
+    m >> k = ReaderT $ \ r -> runReaderT m r >> runReaderT k r
+#endif
+    {-# INLINE (>>) #-}
+#if !(MIN_VERSION_base(4,13,0))
     fail msg = lift (fail msg)
     {-# INLINE fail #-}
+#endif
 
 #if MIN_VERSION_base(4,9,0)
 instance (Fail.MonadFail m) => Fail.MonadFail (ReaderT r m) where
@@ -186,6 +228,12 @@
     mzipWith f (ReaderT m) (ReaderT n) = ReaderT $ \ a ->
         mzipWith f (m a) (n a)
     {-# INLINE mzipWith #-}
+#endif
+
+#if MIN_VERSION_base(4,12,0)
+instance Contravariant m => Contravariant (ReaderT r m) where
+    contramap f = ReaderT . fmap (contramap f) . runReaderT
+    {-# INLINE contramap #-}
 #endif
 
 liftReaderT :: m a -> ReaderT r m a
diff --git a/Control/Monad/Trans/Select.hs b/Control/Monad/Trans/Select.hs
new file mode 100644
--- /dev/null
+++ b/Control/Monad/Trans/Select.hs
@@ -0,0 +1,160 @@
+{-# LANGUAGE CPP #-}
+#if __GLASGOW_HASKELL__ >= 702
+{-# LANGUAGE Safe #-}
+{-# LANGUAGE DeriveGeneric #-}
+#endif
+#if __GLASGOW_HASKELL__ >= 706
+{-# LANGUAGE PolyKinds #-}
+#endif
+#if __GLASGOW_HASKELL__ >= 710 && __GLASGOW_HASKELL__ < 802
+{-# LANGUAGE AutoDeriveTypeable #-}
+#endif
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Control.Monad.Trans.Select
+-- Copyright   :  (c) Ross Paterson 2017
+-- License     :  BSD-style (see the file LICENSE)
+--
+-- Maintainer  :  R.Paterson@city.ac.uk
+-- Stability   :  experimental
+-- Portability :  portable
+--
+-- Selection monad transformer, modelling search algorithms.
+--
+-- * Martin Escardo and Paulo Oliva.
+--   "Selection functions, bar recursion and backward induction",
+--   /Mathematical Structures in Computer Science/ 20:2 (2010), pp. 127-168.
+--   <https://www.cs.bham.ac.uk/~mhe/papers/selection-escardo-oliva.pdf>
+--
+-- * Jules Hedges. "Monad transformers for backtracking search".
+--   In /Proceedings of MSFP 2014/. <https://arxiv.org/abs/1406.2058>
+-----------------------------------------------------------------------------
+
+module Control.Monad.Trans.Select (
+    -- * The Select monad
+    Select,
+    select,
+    runSelect,
+    mapSelect,
+    -- * The SelectT monad transformer
+    SelectT(..),
+    mapSelectT,
+    -- * Monad transformation
+    selectToContT,
+    ) where
+
+import Control.Monad.IO.Class
+import Control.Monad.Trans.Class
+import Control.Monad.Trans.Cont
+
+import Control.Applicative
+import Control.Monad
+#if MIN_VERSION_base(4,9,0)
+import qualified Control.Monad.Fail as Fail
+#endif
+import Data.Functor.Identity
+#if __GLASGOW_HASKELL__ >= 704
+import GHC.Generics
+#endif
+
+-- | The selection monad, which is non-strict.
+type Select r = SelectT r Identity
+
+-- | Constructor for computations in the selection monad.
+select :: ((a -> r) -> a) -> Select r a
+select f = SelectT $ \ k -> Identity (f (runIdentity . k))
+{-# INLINE select #-}
+
+-- | Runs a @Select@ computation with a function for evaluating answers
+-- to select a particular answer.  (The inverse of 'select'.)
+runSelect :: Select r a -> (a -> r) -> a
+runSelect m k = runIdentity (runSelectT m (Identity . k))
+{-# INLINE runSelect #-}
+
+-- | Apply a function to transform the result of a selection computation.
+--
+-- * @'runSelect' ('mapSelect' f m) = f . 'runSelect' m@
+mapSelect :: (a -> a) -> Select r a -> Select r a
+mapSelect f = mapSelectT (Identity . f . runIdentity)
+{-# INLINE mapSelect #-}
+
+-- | Selection monad transformer.
+--
+-- 'SelectT' is not a functor on the category of monads, and many operations
+-- cannot be lifted through it.
+--
+-- @SelectT r m@ is strict if and only if @m@ is.
+newtype SelectT r m a = SelectT {
+    -- | Runs a @SelectT@ computation with a function for evaluating
+    -- answers to select a particular answer.
+    runSelectT :: (a -> m r) -> m a }
+#if __GLASGOW_HASKELL__ >= 704
+    deriving (Generic)
+#endif
+
+-- | Apply a function to transform the result of a selection computation.
+-- This has a more restricted type than the @map@ operations for other
+-- monad transformers, because 'SelectT' does not define a functor in
+-- the category of monads.
+--
+-- * @'runSelectT' ('mapSelectT' f m) = f . 'runSelectT' m@
+mapSelectT :: (m a -> m a) -> SelectT r m a -> SelectT r m a
+mapSelectT f m = SelectT $ f . runSelectT m
+{-# INLINE mapSelectT #-}
+
+instance (Functor m) => Functor (SelectT r m) where
+    fmap f (SelectT g) = SelectT (fmap f . g . (. f))
+    {-# INLINE fmap #-}
+
+instance (Functor m, Monad m) => Applicative (SelectT r m) where
+    pure = lift . return
+    {-# INLINE pure #-}
+    SelectT gf <*> SelectT gx = SelectT $ \ k -> do
+        let h f = liftM f (gx (k . f))
+        f <- gf ((>>= k) . h)
+        h f
+    {-# INLINE (<*>) #-}
+    m *> k = m >>= \_ -> k
+    {-# INLINE (*>) #-}
+
+instance (Functor m, MonadPlus m) => Alternative (SelectT r m) where
+    empty = mzero
+    {-# INLINE empty #-}
+    (<|>) = mplus
+    {-# INLINE (<|>) #-}
+
+instance (Monad m) => Monad (SelectT r m) where
+#if !(MIN_VERSION_base(4,8,0))
+    return = lift . return
+    {-# INLINE return #-}
+#endif
+    SelectT g >>= f = SelectT $ \ k -> do
+        let h x = runSelectT (f x) k
+        y <- g ((>>= k) . h)
+        h y
+    {-# INLINE (>>=) #-}
+
+#if MIN_VERSION_base(4,9,0)
+instance (Fail.MonadFail m) => Fail.MonadFail (SelectT r m) where
+    fail msg = lift (Fail.fail msg)
+    {-# INLINE fail #-}
+#endif
+
+instance (MonadPlus m) => MonadPlus (SelectT r m) where
+    mzero = SelectT (const mzero)
+    {-# INLINE mzero #-}
+    SelectT f `mplus` SelectT g = SelectT $ \ k -> f k `mplus` g k
+    {-# INLINE mplus #-}
+
+instance MonadTrans (SelectT r) where
+    lift = SelectT . const
+    {-# INLINE lift #-}
+
+instance (MonadIO m) => MonadIO (SelectT r m) where
+    liftIO = lift . liftIO
+    {-# INLINE liftIO #-}
+
+-- | Convert a selection computation to a continuation-passing computation.
+selectToContT :: (Monad m) => SelectT r m a -> ContT r m a
+selectToContT (SelectT g) = ContT $ \ k -> g k >>= k
+{-# INLINE selectToContT #-}
diff --git a/Control/Monad/Trans/State/Lazy.hs b/Control/Monad/Trans/State/Lazy.hs
--- a/Control/Monad/Trans/State/Lazy.hs
+++ b/Control/Monad/Trans/State/Lazy.hs
@@ -1,8 +1,9 @@
 {-# LANGUAGE CPP #-}
 #if __GLASGOW_HASKELL__ >= 702
 {-# LANGUAGE Safe #-}
+{-# LANGUAGE DeriveGeneric #-}
 #endif
-#if __GLASGOW_HASKELL__ >= 710
+#if __GLASGOW_HASKELL__ >= 710 && __GLASGOW_HASKELL__ < 802
 {-# LANGUAGE AutoDeriveTypeable #-}
 #endif
 -----------------------------------------------------------------------------
@@ -55,6 +56,7 @@
     put,
     modify,
     modify',
+    modifyM,
     gets,
     -- * Lifting other operations
     liftCallCC,
@@ -62,6 +64,9 @@
     liftCatch,
     liftListen,
     liftPass,
+    -- * Conversion to and from the strict version
+    strictToLazyStateT,
+    lazyToStrictStateT,
     -- * Examples
     -- ** State monads
     -- $examples
@@ -76,6 +81,10 @@
 import Control.Monad.IO.Class
 import Control.Monad.Signatures
 import Control.Monad.Trans.Class
+import qualified Control.Monad.Trans.State.Strict as Strict
+#if MIN_VERSION_base(4,12,0)
+import Data.Functor.Contravariant
+#endif
 import Data.Functor.Identity
 
 import Control.Applicative
@@ -84,6 +93,9 @@
 import qualified Control.Monad.Fail as Fail
 #endif
 import Control.Monad.Fix
+#if __GLASGOW_HASKELL__ >= 704
+import GHC.Generics
+#endif
 
 -- ---------------------------------------------------------------------------
 -- | A state monad parameterized by the type @s@ of the state to carry.
@@ -156,6 +168,9 @@
 -- the final state of the first computation as the initial state of
 -- the second.
 newtype StateT s m a = StateT { runStateT :: s -> m (a,s) }
+#if __GLASGOW_HASKELL__ >= 704
+    deriving (Generic)
+#endif
 
 -- | Evaluate a state computation with the given initial state
 -- and return the final value, discarding the final state.
@@ -206,6 +221,8 @@
         ~(x, s'') <- mx s'
         return (f x, s'')
     {-# INLINE (<*>) #-}
+    m *> k = m >>= \_ -> k
+    {-# INLINE (*>) #-}
 
 instance (Functor m, MonadPlus m) => Alternative (StateT s m) where
     empty = StateT $ \ _ -> mzero
@@ -222,8 +239,10 @@
         ~(a, s') <- runStateT m s
         runStateT (k a) s'
     {-# INLINE (>>=) #-}
+#if !(MIN_VERSION_base(4,13,0))
     fail str = StateT $ \ _ -> fail str
     {-# INLINE fail #-}
+#endif
 
 #if MIN_VERSION_base(4,9,0)
 instance (Fail.MonadFail m) => Fail.MonadFail (StateT s m) where
@@ -251,6 +270,13 @@
     liftIO = lift . liftIO
     {-# INLINE liftIO #-}
 
+#if MIN_VERSION_base(4,12,0)
+instance Contravariant m => Contravariant (StateT s m) where
+    contramap f m = StateT $ \s ->
+      contramap (\ ~(a, s') -> (f a, s')) $ runStateT m s
+    {-# INLINE contramap #-}
+#endif
+
 -- | Fetch the current value of the state within the monad.
 get :: (Monad m) => StateT s m s
 get = state $ \ s -> (s, s)
@@ -279,6 +305,14 @@
     put $! f s
 {-# INLINE modify' #-}
 
+-- | A variant of 'modify' in which the new state is generated by a
+-- monadic action.
+modifyM :: (Monad m) => (s -> m s) -> StateT s m ()
+modifyM f = StateT $ \ s -> do
+    s' <- f s
+    return ((), s')
+{-# INLINE modifyM #-}
+
 -- | Get a specific component of the state, using a projection function
 -- supplied.
 --
@@ -306,6 +340,9 @@
 {-# INLINE liftCallCC' #-}
 
 -- | Lift a @catchE@ operation to the new monad.
+-- The uniformity property (see "Control.Monad.Signatures") implies
+-- that the lifted @catchE@ rolls back to the original state on entering
+-- the handler.
 liftCatch :: Catch e m (a,s) -> Catch e (StateT s m) a
 liftCatch catchE m h =
     StateT $ \ s -> runStateT m s `catchE` \ e -> runStateT (h e) s
@@ -324,6 +361,16 @@
     ~((a, f), s') <- runStateT m s
     return ((a, s'), f)
 {-# INLINE liftPass #-}
+
+-- | Convert from the strict version to the lazy version
+strictToLazyStateT :: Strict.StateT s m a -> StateT s m a
+strictToLazyStateT (Strict.StateT f) = StateT f
+{-# INLINE strictToLazyStateT #-}
+
+-- | Convert from the lazy version to the strict version
+lazyToStrictStateT :: StateT s m a -> Strict.StateT s m a
+lazyToStrictStateT (StateT f) = Strict.StateT f
+{-# INLINE lazyToStrictStateT #-}
 
 {- $examples
 
diff --git a/Control/Monad/Trans/State/Strict.hs b/Control/Monad/Trans/State/Strict.hs
--- a/Control/Monad/Trans/State/Strict.hs
+++ b/Control/Monad/Trans/State/Strict.hs
@@ -1,8 +1,9 @@
 {-# LANGUAGE CPP #-}
 #if __GLASGOW_HASKELL__ >= 702
 {-# LANGUAGE Safe #-}
+{-# LANGUAGE DeriveGeneric #-}
 #endif
-#if __GLASGOW_HASKELL__ >= 710
+#if __GLASGOW_HASKELL__ >= 710 && __GLASGOW_HASKELL__ < 802
 {-# LANGUAGE AutoDeriveTypeable #-}
 #endif
 -----------------------------------------------------------------------------
@@ -52,6 +53,7 @@
     put,
     modify,
     modify',
+    modifyM,
     gets,
     -- * Lifting other operations
     liftCallCC,
@@ -73,6 +75,9 @@
 import Control.Monad.IO.Class
 import Control.Monad.Signatures
 import Control.Monad.Trans.Class
+#if MIN_VERSION_base(4,12,0)
+import Data.Functor.Contravariant
+#endif
 import Data.Functor.Identity
 
 import Control.Applicative
@@ -81,6 +86,9 @@
 import qualified Control.Monad.Fail as Fail
 #endif
 import Control.Monad.Fix
+#if __GLASGOW_HASKELL__ >= 704
+import GHC.Generics
+#endif
 
 -- ---------------------------------------------------------------------------
 -- | A state monad parameterized by the type @s@ of the state to carry.
@@ -153,6 +161,9 @@
 -- the final state of the first computation as the initial state of
 -- the second.
 newtype StateT s m a = StateT { runStateT :: s -> m (a,s) }
+#if __GLASGOW_HASKELL__ >= 704
+    deriving (Generic)
+#endif
 
 -- | Evaluate a state computation with the given initial state
 -- and return the final value, discarding the final state.
@@ -203,6 +214,8 @@
         (x, s'') <- mx s'
         return (f x, s'')
     {-# INLINE (<*>) #-}
+    m *> k = m >>= \_ -> k
+    {-# INLINE (*>) #-}
 
 instance (Functor m, MonadPlus m) => Alternative (StateT s m) where
     empty = StateT $ \ _ -> mzero
@@ -219,8 +232,10 @@
         (a, s') <- runStateT m s
         runStateT (k a) s'
     {-# INLINE (>>=) #-}
+#if !(MIN_VERSION_base(4,13,0))
     fail str = StateT $ \ _ -> fail str
     {-# INLINE fail #-}
+#endif
 
 #if MIN_VERSION_base(4,9,0)
 instance (Fail.MonadFail m) => Fail.MonadFail (StateT s m) where
@@ -248,6 +263,13 @@
     liftIO = lift . liftIO
     {-# INLINE liftIO #-}
 
+#if MIN_VERSION_base(4,12,0)
+instance Contravariant m => Contravariant (StateT s m) where
+    contramap f m = StateT $ \s ->
+      contramap (\ (a, s') -> (f a, s')) $ runStateT m s
+    {-# INLINE contramap #-}
+#endif
+
 -- | Fetch the current value of the state within the monad.
 get :: (Monad m) => StateT s m s
 get = state $ \ s -> (s, s)
@@ -270,12 +292,24 @@
 -- new state.
 --
 -- * @'modify'' f = 'get' >>= (('$!') 'put' . f)@
+--
+-- Note that this is only strict in the top level of the state.
+-- Lazy components of the state will not be evaluated unless @f@
+-- evaluates them.
 modify' :: (Monad m) => (s -> s) -> StateT s m ()
 modify' f = do
     s <- get
     put $! f s
 {-# INLINE modify' #-}
 
+-- | A variant of 'modify' in which the new state is generated by a
+-- monadic action.
+modifyM :: (Monad m) => (s -> m s) -> StateT s m ()
+modifyM f = StateT $ \ s -> do
+    s' <- f s
+    return ((), s')
+{-# INLINE modifyM #-}
+
 -- | Get a specific component of the state, using a projection function
 -- supplied.
 --
@@ -303,6 +337,9 @@
 {-# INLINE liftCallCC' #-}
 
 -- | Lift a @catchE@ operation to the new monad.
+-- The uniformity property (see "Control.Monad.Signatures") implies
+-- that the lifted @catchE@ rolls back to the original state on entering
+-- the handler.
 liftCatch :: Catch e m (a,s) -> Catch e (StateT s m) a
 liftCatch catchE m h =
     StateT $ \ s -> runStateT m s `catchE` \ e -> runStateT (h e) s
diff --git a/Control/Monad/Trans/Writer.hs b/Control/Monad/Trans/Writer.hs
--- a/Control/Monad/Trans/Writer.hs
+++ b/Control/Monad/Trans/Writer.hs
@@ -14,8 +14,8 @@
 -- Portability :  portable
 --
 -- The WriterT monad transformer.
--- This version is lazy; for a strict version, see
--- "Control.Monad.Trans.Writer.Strict", which has the same interface.
+-- This version builds its output lazily; for a constant-space version
+-- with almost the same interface, see "Control.Monad.Trans.Writer.CPS".
 -----------------------------------------------------------------------------
 
 module Control.Monad.Trans.Writer (
diff --git a/Control/Monad/Trans/Writer/CPS.hs b/Control/Monad/Trans/Writer/CPS.hs
new file mode 100644
--- /dev/null
+++ b/Control/Monad/Trans/Writer/CPS.hs
@@ -0,0 +1,301 @@
+{-# LANGUAGE CPP #-}
+#if __GLASGOW_HASKELL__ >= 702
+{-# LANGUAGE Safe #-}
+{-# LANGUAGE DeriveGeneric #-}
+#endif
+#if __GLASGOW_HASKELL__ >= 710 && __GLASGOW_HASKELL__ < 802
+{-# LANGUAGE AutoDeriveTypeable #-}
+#endif
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Control.Monad.Trans.Writer.CPS
+-- Copyright   :  (c) Daniel Mendler 2016,
+--                (c) Andy Gill 2001,
+--                (c) Oregon Graduate Institute of Science and Technology, 2001
+-- License     :  BSD-style (see the file LICENSE)
+--
+-- Maintainer  :  R.Paterson@city.ac.uk
+-- Stability   :  experimental
+-- Portability :  portable
+--
+-- The strict 'WriterT' monad transformer, which adds collection of
+-- outputs (such as a count or string output) to a given monad.
+--
+-- This monad transformer provides only limited access to the output
+-- during the computation. For more general access, use
+-- "Control.Monad.Trans.State" instead.
+--
+-- This version builds its output strictly and uses continuation-passing-style
+-- to achieve constant space usage. This transformer can be used as a
+-- drop-in replacement for "Control.Monad.Trans.Writer.Strict".
+-----------------------------------------------------------------------------
+
+module Control.Monad.Trans.Writer.CPS (
+    -- * The Writer monad
+    Writer,
+    writer,
+    runWriter,
+    execWriter,
+    mapWriter,
+    -- * The WriterT monad transformer
+    WriterT,
+    writerT,
+    runWriterT,
+    execWriterT,
+    mapWriterT,
+    -- * Writer operations
+    tell,
+    listen,
+    listens,
+    pass,
+    censor,
+    -- * Lifting other operations
+    liftCallCC,
+    liftCatch,
+  ) where
+
+import Control.Applicative
+import Control.Monad
+import Control.Monad.Fix
+import Control.Monad.IO.Class
+import Control.Monad.Trans.Class
+import Control.Monad.Signatures
+import Data.Functor.Identity
+
+#if !(MIN_VERSION_base(4,8,0))
+import Data.Monoid
+#endif
+
+#if MIN_VERSION_base(4,9,0)
+import qualified Control.Monad.Fail as Fail
+#endif
+#if __GLASGOW_HASKELL__ >= 704
+import GHC.Generics
+#endif
+
+-- ---------------------------------------------------------------------------
+-- | A writer monad parameterized by the type @w@ of output to accumulate.
+--
+-- The 'return' function produces the output 'mempty', while @m '>>=' k@
+-- combines the outputs of the subcomputations using 'mappend' (also
+-- known as @<>@):
+--
+-- <<images/bind-WriterT.svg>>
+--
+type Writer w = WriterT w Identity
+
+-- | Construct a writer computation from a (result, output) pair.
+-- (The inverse of 'runWriter'.)
+writer :: (Monoid w, Monad m) => (a, w) -> WriterT w m a
+writer (a, w') = WriterT $ \ w ->
+    let wt = w `mappend` w' in wt `seq` return (a, wt)
+{-# INLINE writer #-}
+
+-- | Unwrap a writer computation as a (result, output) pair.
+-- (The inverse of 'writer'.)
+runWriter :: (Monoid w) => Writer w a -> (a, w)
+runWriter = runIdentity . runWriterT
+{-# INLINE runWriter #-}
+
+-- | Extract the output from a writer computation.
+--
+-- * @'execWriter' m = 'snd' ('runWriter' m)@
+execWriter :: (Monoid w) => Writer w a -> w
+execWriter = runIdentity . execWriterT
+{-# INLINE execWriter #-}
+
+-- | Map both the return value and output of a computation using
+-- the given function.
+--
+-- * @'runWriter' ('mapWriter' f m) = f ('runWriter' m)@
+mapWriter :: (Monoid w, Monoid w') =>
+    ((a, w) -> (b, w')) -> Writer w a -> Writer w' b
+mapWriter f = mapWriterT (Identity . f . runIdentity)
+{-# INLINE mapWriter #-}
+
+-- ---------------------------------------------------------------------------
+-- | A writer monad parameterized by:
+--
+--   * @w@ - the output to accumulate.
+--
+--   * @m@ - The inner monad.
+--
+-- The 'return' function produces the output 'mempty', while @m '>>=' k@
+-- combines the outputs of the subcomputations using 'mappend' (also
+-- known as @<>@):
+--
+-- <<images/bind-WriterT.svg>>
+--
+newtype WriterT w m a = WriterT { unWriterT :: w -> m (a, w) }
+#if __GLASGOW_HASKELL__ >= 704
+    deriving (Generic)
+#endif
+
+-- | Construct a writer computation from a (result, output) computation.
+-- (The inverse of 'runWriterT'.)
+writerT :: (Functor m, Monoid w) => m (a, w) -> WriterT w m a
+writerT f = WriterT $ \ w ->
+    (\ (a, w') -> let wt = w `mappend` w' in wt `seq` (a, wt)) <$> f
+{-# INLINE writerT #-}
+
+-- | Unwrap a writer computation.
+-- (The inverse of 'writerT'.)
+runWriterT :: (Monoid w) => WriterT w m a -> m (a, w)
+runWriterT m = unWriterT m mempty
+{-# INLINE runWriterT #-}
+
+-- | Extract the output from a writer computation.
+--
+-- * @'execWriterT' m = 'liftM' 'snd' ('runWriterT' m)@
+execWriterT :: (Monad m, Monoid w) => WriterT w m a -> m w
+execWriterT m = do
+    (_, w) <- runWriterT m
+    return w
+{-# INLINE execWriterT #-}
+
+-- | Map both the return value and output of a computation using
+-- the given function.
+--
+-- * @'runWriterT' ('mapWriterT' f m) = f ('runWriterT' m)@
+mapWriterT :: (Monad n, Monoid w, Monoid w') =>
+    (m (a, w) -> n (b, w')) -> WriterT w m a -> WriterT w' n b
+mapWriterT f m = WriterT $ \ w -> do
+    (a, w') <- f (runWriterT m)
+    let wt = w `mappend` w'
+    wt `seq` return (a, wt)
+{-# INLINE mapWriterT #-}
+
+instance (Functor m) => Functor (WriterT w m) where
+    fmap f m = WriterT $ \ w -> (\ (a, w') -> (f a, w')) <$> unWriterT m w
+    {-# INLINE fmap #-}
+
+instance (Functor m, Monad m) => Applicative (WriterT w m) where
+    pure a = WriterT $ \ w -> return (a, w)
+    {-# INLINE pure #-}
+
+    WriterT mf <*> WriterT mx = WriterT $ \ w -> do
+        (f, w') <- mf w
+        (x, w'') <- mx w'
+        return (f x, w'')
+    {-# INLINE (<*>) #-}
+
+instance (Functor m, MonadPlus m) => Alternative (WriterT w m) where
+    empty = WriterT $ const mzero
+    {-# INLINE empty #-}
+
+    WriterT m <|> WriterT n = WriterT $ \ w -> m w `mplus` n w
+    {-# INLINE (<|>) #-}
+
+instance (Monad m) => Monad (WriterT w m) where
+#if !(MIN_VERSION_base(4,8,0))
+    return a = WriterT $ \ w -> return (a, w)
+    {-# INLINE return #-}
+#endif
+
+    m >>= k = WriterT $ \ w -> do
+        (a, w') <- unWriterT m w
+        unWriterT (k a) w'
+    {-# INLINE (>>=) #-}
+
+#if !(MIN_VERSION_base(4,13,0))
+    fail msg = WriterT $ \ _ -> fail msg
+    {-# INLINE fail #-}
+#endif
+
+#if MIN_VERSION_base(4,9,0)
+instance (Fail.MonadFail m) => Fail.MonadFail (WriterT w m) where
+    fail msg = WriterT $ \ _ -> Fail.fail msg
+    {-# INLINE fail #-}
+#endif
+
+instance (Functor m, MonadPlus m) => MonadPlus (WriterT w m) where
+    mzero = empty
+    {-# INLINE mzero #-}
+    mplus = (<|>)
+    {-# INLINE mplus #-}
+
+instance (MonadFix m) => MonadFix (WriterT w m) where
+    mfix f = WriterT $ \ w -> mfix $ \ ~(a, _) -> unWriterT (f a) w
+    {-# INLINE mfix #-}
+
+instance MonadTrans (WriterT w) where
+    lift m = WriterT $ \ w -> do
+        a <- m
+        return (a, w)
+    {-# INLINE lift #-}
+
+instance (MonadIO m) => MonadIO (WriterT w m) where
+    liftIO = lift . liftIO
+    {-# INLINE liftIO #-}
+
+-- | @'tell' w@ is an action that produces the output @w@.
+tell :: (Monoid w, Monad m) => w -> WriterT w m ()
+tell w = writer ((), w)
+{-# INLINE tell #-}
+
+-- | @'listen' m@ is an action that executes the action @m@ and adds its
+-- output to the value of the computation.
+--
+-- * @'runWriterT' ('listen' m) = 'liftM' (\\ (a, w) -> ((a, w), w)) ('runWriterT' m)@
+listen :: (Monoid w, Monad m) => WriterT w m a -> WriterT w m (a, w)
+listen = listens id
+{-# INLINE listen #-}
+
+-- | @'listens' f m@ is an action that executes the action @m@ and adds
+-- the result of applying @f@ to the output to the value of the computation.
+--
+-- * @'listens' f m = 'liftM' (id *** f) ('listen' m)@
+--
+-- * @'runWriterT' ('listens' f m) = 'liftM' (\\ (a, w) -> ((a, f w), w)) ('runWriterT' m)@
+listens :: (Monoid w, Monad m) =>
+    (w -> b) -> WriterT w m a -> WriterT w m (a, b)
+listens f m = WriterT $ \ w -> do
+    (a, w') <- runWriterT m
+    let wt = w `mappend` w'
+    wt `seq` return ((a, f w'), wt)
+{-# INLINE listens #-}
+
+-- | @'pass' m@ is an action that executes the action @m@, which returns
+-- a value and a function, and returns the value, applying the function
+-- to the output.
+--
+-- * @'runWriterT' ('pass' m) = 'liftM' (\\ ((a, f), w) -> (a, f w)) ('runWriterT' m)@
+pass :: (Monoid w, Monoid w', Monad m) =>
+    WriterT w m (a, w -> w') -> WriterT w' m a
+pass m = WriterT $ \ w -> do
+    ((a, f), w') <- runWriterT m
+    let wt = w `mappend` f w'
+    wt `seq` return (a, wt)
+{-# INLINE pass #-}
+
+-- | @'censor' f m@ is an action that executes the action @m@ and
+-- applies the function @f@ to its output, leaving the return value
+-- unchanged.
+--
+-- * @'censor' f m = 'pass' ('liftM' (\\ x -> (x,f)) m)@
+--
+-- * @'runWriterT' ('censor' f m) = 'liftM' (\\ (a, w) -> (a, f w)) ('runWriterT' m)@
+censor :: (Monoid w, Monad m) => (w -> w) -> WriterT w m a -> WriterT w m a
+censor f m = WriterT $ \ w -> do
+    (a, w') <- runWriterT m
+    let wt = w `mappend` f w'
+    wt `seq` return (a, wt)
+{-# INLINE censor #-}
+
+-- | Uniform lifting of a @callCC@ operation to the new monad.
+-- The uniformity property (see "Control.Monad.Signatures") implies that
+-- the lifted @callCC@ discards any output from the body on entering
+-- the saved continuation.
+liftCallCC :: CallCC m (a, w) (b, w) -> CallCC (WriterT w m) a b
+liftCallCC callCC f = WriterT $ \ w ->
+    callCC $ \ c -> unWriterT (f (\ a -> WriterT $ \ _ -> c (a, w))) w
+{-# INLINE liftCallCC #-}
+
+-- | Lift a @catchE@ operation to the new monad.
+-- The uniformity property (see "Control.Monad.Signatures") implies that
+-- the lifted @catchE@ discards any output from the body on entering
+-- the handler.
+liftCatch :: Catch e m (a, w) -> Catch e (WriterT w m) a
+liftCatch catchE m h = WriterT $ \ w ->
+    unWriterT m w `catchE` \ e -> unWriterT (h e) w
+{-# INLINE liftCatch #-}
diff --git a/Control/Monad/Trans/Writer/Lazy.hs b/Control/Monad/Trans/Writer/Lazy.hs
--- a/Control/Monad/Trans/Writer/Lazy.hs
+++ b/Control/Monad/Trans/Writer/Lazy.hs
@@ -1,8 +1,9 @@
 {-# LANGUAGE CPP #-}
 #if __GLASGOW_HASKELL__ >= 702
 {-# LANGUAGE Safe #-}
+{-# LANGUAGE DeriveGeneric #-}
 #endif
-#if __GLASGOW_HASKELL__ >= 710
+#if __GLASGOW_HASKELL__ >= 710 && __GLASGOW_HASKELL__ < 802
 {-# LANGUAGE AutoDeriveTypeable #-}
 #endif
 -----------------------------------------------------------------------------
@@ -23,8 +24,8 @@
 -- during the computation.  For more general access, use
 -- "Control.Monad.Trans.State" instead.
 --
--- This version builds its output lazily; for a strict version with
--- the same interface, see "Control.Monad.Trans.Writer.Strict".
+-- This version builds its output lazily; for a constant-space version
+-- with almost the same interface, see "Control.Monad.Trans.Writer.CPS".
 -----------------------------------------------------------------------------
 
 module Control.Monad.Trans.Writer.Lazy (
@@ -52,6 +53,9 @@
 import Control.Monad.IO.Class
 import Control.Monad.Trans.Class
 import Data.Functor.Classes
+#if MIN_VERSION_base(4,12,0)
+import Data.Functor.Contravariant
+#endif
 import Data.Functor.Identity
 
 import Control.Applicative
@@ -64,15 +68,25 @@
 #if MIN_VERSION_base(4,4,0)
 import Control.Monad.Zip (MonadZip(mzipWith))
 #endif
-import Data.Foldable (Foldable(foldMap))
+import Data.Foldable
 import Data.Monoid
+#if !(MIN_VERSION_base(4,8,0)) || defined(__MHS__)
 import Data.Traversable (Traversable(traverse))
+#endif
+import Prelude hiding (null, length)
+#if __GLASGOW_HASKELL__ >= 704
+import GHC.Generics
+#endif
 
 -- ---------------------------------------------------------------------------
 -- | A writer monad parameterized by the type @w@ of output to accumulate.
 --
--- The 'return' function produces the output 'mempty', while @>>=@
--- combines the outputs of the subcomputations using 'mappend'.
+-- The 'return' function produces the output 'mempty', while @m '>>=' k@
+-- combines the outputs of the subcomputations using 'mappend' (also
+-- known as @<>@):
+--
+-- <<images/bind-WriterT.svg>>
+--
 type Writer w = WriterT w Identity
 
 -- | Construct a writer computation from a (result, output) pair.
@@ -109,9 +123,16 @@
 --
 --   * @m@ - The inner monad.
 --
--- The 'return' function produces the output 'mempty', while @>>=@
--- combines the outputs of the subcomputations using 'mappend'.
+-- The 'return' function produces the output 'mempty', while @m '>>=' k@
+-- combines the outputs of the subcomputations using 'mappend' (also
+-- known as @<>@):
+--
+-- <<images/bind-WriterT.svg>>
+--
 newtype WriterT w m a = WriterT { runWriterT :: m (a, w) }
+#if __GLASGOW_HASKELL__ >= 704
+    deriving (Generic)
+#endif
 
 instance (Eq w, Eq1 m) => Eq1 (WriterT w m) where
     liftEq eq (WriterT m1) (WriterT m2) = liftEq (liftEq2 eq (==)) m1 m2
@@ -167,6 +188,10 @@
 instance (Foldable f) => Foldable (WriterT w f) where
     foldMap f = foldMap (f . fst) . runWriterT
     {-# INLINE foldMap #-}
+#if MIN_VERSION_base(4,8,0)
+    null (WriterT t) = null t
+    length (WriterT t) = length t
+#endif
 
 instance (Traversable f) => Traversable (WriterT w f) where
     traverse f = fmap WriterT . traverse f' . runWriterT where
@@ -196,8 +221,10 @@
         ~(b, w') <- runWriterT (k a)
         return (b, w `mappend` w')
     {-# INLINE (>>=) #-}
+#if !(MIN_VERSION_base(4,13,0))
     fail msg = WriterT $ fail msg
     {-# INLINE fail #-}
+#endif
 
 #if MIN_VERSION_base(4,9,0)
 instance (Monoid w, Fail.MonadFail m) => Fail.MonadFail (WriterT w m) where
@@ -232,6 +259,12 @@
     {-# INLINE mzipWith #-}
 #endif
 
+#if MIN_VERSION_base(4,12,0)
+instance Contravariant m => Contravariant (WriterT w m) where
+    contramap f = mapWriterT $ contramap $ \ ~(a, w) -> (f a, w)
+    {-# INLINE contramap #-}
+#endif
+
 -- | @'tell' w@ is an action that produces the output @w@.
 tell :: (Monad m) => w -> WriterT w m ()
 tell w = writer ((), w)
@@ -284,6 +317,9 @@
 {-# INLINE censor #-}
 
 -- | Lift a @callCC@ operation to the new monad.
+-- The uniformity property (see "Control.Monad.Signatures") implies that
+-- the lifted @callCC@ discards any output from the body on entering
+-- the saved condinuation.
 liftCallCC :: (Monoid w) => CallCC m (a,w) (b,w) -> CallCC (WriterT w m) a b
 liftCallCC callCC f = WriterT $
     callCC $ \ c ->
@@ -291,6 +327,9 @@
 {-# INLINE liftCallCC #-}
 
 -- | Lift a @catchE@ operation to the new monad.
+-- The uniformity property (see "Control.Monad.Signatures") implies that
+-- the lifted @catchE@ discards any output from the body on entering
+-- the handler.
 liftCatch :: Catch e m (a,w) -> Catch e (WriterT w m) a
 liftCatch catchE m h =
     WriterT $ runWriterT m `catchE` \ e -> runWriterT (h e)
diff --git a/Control/Monad/Trans/Writer/Strict.hs b/Control/Monad/Trans/Writer/Strict.hs
--- a/Control/Monad/Trans/Writer/Strict.hs
+++ b/Control/Monad/Trans/Writer/Strict.hs
@@ -1,8 +1,9 @@
 {-# LANGUAGE CPP #-}
 #if __GLASGOW_HASKELL__ >= 702
 {-# LANGUAGE Safe #-}
+{-# LANGUAGE DeriveGeneric #-}
 #endif
-#if __GLASGOW_HASKELL__ >= 710
+#if __GLASGOW_HASKELL__ >= 710 && __GLASGOW_HASKELL__ < 802
 {-# LANGUAGE AutoDeriveTypeable #-}
 #endif
 -----------------------------------------------------------------------------
@@ -27,7 +28,7 @@
 -- the same interface, see "Control.Monad.Trans.Writer.Lazy".
 -- Although the output is built strictly, it is not possible to
 -- achieve constant space behaviour with this transformer: for that,
--- use "Control.Monad.Trans.State.Strict" instead.
+-- use "Control.Monad.Trans.Writer.CPS" instead.
 -----------------------------------------------------------------------------
 
 module Control.Monad.Trans.Writer.Strict (
@@ -55,6 +56,9 @@
 import Control.Monad.IO.Class
 import Control.Monad.Trans.Class
 import Data.Functor.Classes
+#if MIN_VERSION_base(4,12,0)
+import Data.Functor.Contravariant
+#endif
 import Data.Functor.Identity
 
 import Control.Applicative
@@ -67,15 +71,25 @@
 #if MIN_VERSION_base(4,4,0)
 import Control.Monad.Zip (MonadZip(mzipWith))
 #endif
-import Data.Foldable (Foldable(foldMap))
+import Data.Foldable
 import Data.Monoid
+#if !(MIN_VERSION_base(4,8,0)) || defined(__MHS__)
 import Data.Traversable (Traversable(traverse))
+#endif
+import Prelude hiding (null, length)
+#if __GLASGOW_HASKELL__ >= 704
+import GHC.Generics
+#endif
 
 -- ---------------------------------------------------------------------------
 -- | A writer monad parameterized by the type @w@ of output to accumulate.
 --
--- The 'return' function produces the output 'mempty', while @>>=@
--- combines the outputs of the subcomputations using 'mappend'.
+-- The 'return' function produces the output 'mempty', while @m '>>=' k@
+-- combines the outputs of the subcomputations using 'mappend' (also
+-- known as @<>@):
+--
+-- <<images/bind-WriterT.svg>>
+--
 type Writer w = WriterT w Identity
 
 -- | Construct a writer computation from a (result, output) pair.
@@ -112,9 +126,16 @@
 --
 --   * @m@ - The inner monad.
 --
--- The 'return' function produces the output 'mempty', while @>>=@
--- combines the outputs of the subcomputations using 'mappend'.
+-- The 'return' function produces the output 'mempty', while @m '>>=' k@
+-- combines the outputs of the subcomputations using 'mappend' (also
+-- known as @<>@):
+--
+-- <<images/bind-WriterT.svg>>
+--
 newtype WriterT w m a = WriterT { runWriterT :: m (a, w) }
+#if __GLASGOW_HASKELL__ >= 704
+    deriving (Generic)
+#endif
 
 instance (Eq w, Eq1 m) => Eq1 (WriterT w m) where
     liftEq eq (WriterT m1) (WriterT m2) = liftEq (liftEq2 eq (==)) m1 m2
@@ -170,6 +191,10 @@
 instance (Foldable f) => Foldable (WriterT w f) where
     foldMap f = foldMap (f . fst) . runWriterT
     {-# INLINE foldMap #-}
+#if MIN_VERSION_base(4,8,0)
+    null (WriterT t) = null t
+    length (WriterT t) = length t
+#endif
 
 instance (Traversable f) => Traversable (WriterT w f) where
     traverse f = fmap WriterT . traverse f' . runWriterT where
@@ -199,8 +224,10 @@
         (b, w') <- runWriterT (k a)
         return (b, w `mappend` w')
     {-# INLINE (>>=) #-}
+#if !(MIN_VERSION_base(4,13,0))
     fail msg = WriterT $ fail msg
     {-# INLINE fail #-}
+#endif
 
 #if MIN_VERSION_base(4,9,0)
 instance (Monoid w, Fail.MonadFail m) => Fail.MonadFail (WriterT w m) where
@@ -235,6 +262,12 @@
     {-# INLINE mzipWith #-}
 #endif
 
+#if MIN_VERSION_base(4,12,0)
+instance Contravariant m => Contravariant (WriterT w m) where
+    contramap f = mapWriterT $ contramap $ \ (a, w) -> (f a, w)
+    {-# INLINE contramap #-}
+#endif
+
 -- | @'tell' w@ is an action that produces the output @w@.
 tell :: (Monad m) => w -> WriterT w m ()
 tell w = writer ((), w)
@@ -287,6 +320,9 @@
 {-# INLINE censor #-}
 
 -- | Lift a @callCC@ operation to the new monad.
+-- The uniformity property (see "Control.Monad.Signatures") implies that
+-- the lifted @callCC@ discards any output from the body on entering
+-- the saved continuation.
 liftCallCC :: (Monoid w) => CallCC m (a,w) (b,w) -> CallCC (WriterT w m) a b
 liftCallCC callCC f = WriterT $
     callCC $ \ c ->
@@ -294,6 +330,9 @@
 {-# INLINE liftCallCC #-}
 
 -- | Lift a @catchE@ operation to the new monad.
+-- The uniformity property (see "Control.Monad.Signatures") implies that
+-- the lifted @catchE@ discards any output from the body on entering
+-- the handler.
 liftCatch :: Catch e m (a,w) -> Catch e (WriterT w m) a
 liftCatch catchE m h =
     WriterT $ runWriterT m `catchE` \ e -> runWriterT (h e)
diff --git a/Data/Functor/Constant.hs b/Data/Functor/Constant.hs
--- a/Data/Functor/Constant.hs
+++ b/Data/Functor/Constant.hs
@@ -1,11 +1,15 @@
 {-# LANGUAGE CPP #-}
+#if __GLASGOW_HASKELL__ >= 800
+{-# LANGUAGE DeriveDataTypeable #-}
+#endif
 #if __GLASGOW_HASKELL__ >= 702
 {-# LANGUAGE Safe #-}
+{-# LANGUAGE DeriveGeneric #-}
 #endif
 #if __GLASGOW_HASKELL__ >= 706
 {-# LANGUAGE PolyKinds #-}
 #endif
-#if __GLASGOW_HASKELL__ >= 710
+#if __GLASGOW_HASKELL__ >= 710 && __GLASGOW_HASKELL__ < 802
 {-# LANGUAGE AutoDeriveTypeable #-}
 #endif
 -----------------------------------------------------------------------------
@@ -26,18 +30,46 @@
   ) where
 
 import Data.Functor.Classes
+#if MIN_VERSION_base(4,12,0)
+import Data.Functor.Contravariant
+#endif
 
 import Control.Applicative
-import Data.Foldable (Foldable(foldMap))
+import Data.Foldable
+#if !(MIN_VERSION_base(4,8,0)) || defined(__MHS__)
 import Data.Monoid (Monoid(..))
 import Data.Traversable (Traversable(traverse))
+#endif
 #if MIN_VERSION_base(4,8,0)
 import Data.Bifunctor (Bifunctor(..))
 #endif
+#if (MIN_VERSION_base(4,9,0)) && !(MIN_VERSION_base(4,11,0))
+import Data.Semigroup (Semigroup((<>)))
+#endif
+#if MIN_VERSION_base(4,10,0)
+import Data.Bifoldable (Bifoldable(..))
+import Data.Bitraversable (Bitraversable(..))
+#endif
+import Prelude hiding (null, length)
+#if __GLASGOW_HASKELL__ >= 800
+import Data.Data
+#endif
+#if __GLASGOW_HASKELL__ >= 704
+import GHC.Generics
+#endif
 
 -- | Constant functor.
 newtype Constant a b = Constant { getConstant :: a }
-    deriving (Eq, Ord)
+    deriving (Eq, Ord
+#if __GLASGOW_HASKELL__ >= 800
+        , Data
+#endif
+#if __GLASGOW_HASKELL__ >= 710
+        , Generic, Generic1
+#elif __GLASGOW_HASKELL__ >= 704
+        , Generic
+#endif
+        )
 
 -- These instances would be equivalent to the derived instances of the
 -- newtype if the field were removed.
@@ -86,11 +118,21 @@
 instance Foldable (Constant a) where
     foldMap _ (Constant _) = mempty
     {-# INLINE foldMap #-}
+#if MIN_VERSION_base(4,8,0)
+    null (Constant _) = True
+    length (Constant _) = 0
+#endif
 
 instance Traversable (Constant a) where
     traverse _ (Constant x) = pure (Constant x)
     {-# INLINE traverse #-}
 
+#if MIN_VERSION_base(4,9,0)
+instance (Semigroup a) => Semigroup (Constant a b) where
+    Constant x <> Constant y = Constant (x <> y)
+    {-# INLINE (<>) #-}
+#endif
+
 instance (Monoid a) => Applicative (Constant a) where
     pure _ = Constant mempty
     {-# INLINE pure #-}
@@ -100,8 +142,11 @@
 instance (Monoid a) => Monoid (Constant a b) where
     mempty = Constant mempty
     {-# INLINE mempty #-}
+#if !MIN_VERSION_base(4,11,0)
+    -- From base-4.11, Monoid(mappend) defaults to Semigroup((<>))
     Constant x `mappend` Constant y = Constant (x `mappend` y)
     {-# INLINE mappend #-}
+#endif
 
 #if MIN_VERSION_base(4,8,0)
 instance Bifunctor Constant where
@@ -109,4 +154,20 @@
     {-# INLINE first #-}
     second _ (Constant x) = Constant x
     {-# INLINE second #-}
+#endif
+
+#if MIN_VERSION_base(4,10,0)
+instance Bifoldable Constant where
+    bifoldMap f _ (Constant a) = f a
+    {-# INLINE bifoldMap #-}
+
+instance Bitraversable Constant where
+    bitraverse f _ (Constant a) = Constant <$> f a
+    {-# INLINE bitraverse #-}
+#endif
+
+#if MIN_VERSION_base(4,12,0)
+instance Contravariant (Constant a) where
+    contramap _ (Constant a) = Constant a
+    {-# INLINE contramap #-}
 #endif
diff --git a/Data/Functor/Reverse.hs b/Data/Functor/Reverse.hs
--- a/Data/Functor/Reverse.hs
+++ b/Data/Functor/Reverse.hs
@@ -1,11 +1,12 @@
 {-# LANGUAGE CPP #-}
 #if __GLASGOW_HASKELL__ >= 702
 {-# LANGUAGE Safe #-}
+{-# LANGUAGE DeriveGeneric #-}
 #endif
 #if __GLASGOW_HASKELL__ >= 706
 {-# LANGUAGE PolyKinds #-}
 #endif
-#if __GLASGOW_HASKELL__ >= 710
+#if __GLASGOW_HASKELL__ >= 710 && __GLASGOW_HASKELL__ < 802
 {-# LANGUAGE AutoDeriveTypeable #-}
 #endif
 -----------------------------------------------------------------------------
@@ -27,17 +28,37 @@
   ) where
 
 import Control.Applicative.Backwards
+#if MIN_VERSION_base(4,18,0)
+import Data.Foldable1 (Foldable1(foldMap1))
+#endif
 import Data.Functor.Classes
+#if MIN_VERSION_base(4,12,0)
+import Data.Functor.Contravariant
+#endif
 
-import Prelude hiding (foldr, foldr1, foldl, foldl1)
+import Prelude hiding (foldr, foldr1, foldl, foldl1, null, length)
 import Control.Applicative
+import Control.Monad
+#if MIN_VERSION_base(4,9,0)
+import qualified Control.Monad.Fail as Fail
+#endif
 import Data.Foldable
-import Data.Traversable
+#if !(MIN_VERSION_base(4,8,0)) || defined(__MHS__)
+import Data.Traversable (Traversable(traverse))
+#endif
 import Data.Monoid
+#if __GLASGOW_HASKELL__ >= 704
+import GHC.Generics
+#endif
 
 -- | The same functor, but with 'Foldable' and 'Traversable' instances
 -- that process the elements in the reverse order.
 newtype Reverse f a = Reverse { getReverse :: f a }
+#if __GLASGOW_HASKELL__ >= 710
+    deriving (Generic, Generic1)
+#elif __GLASGOW_HASKELL__ >= 704
+    deriving (Generic)
+#endif
 
 instance (Eq1 f) => Eq1 (Reverse f) where
     liftEq eq (Reverse x) (Reverse y) = liftEq eq x y
@@ -79,6 +100,32 @@
     Reverse x <|> Reverse y = Reverse (x <|> y)
     {-# INLINE (<|>) #-}
 
+-- | Derived instance.
+instance (Monad m) => Monad (Reverse m) where
+#if !(MIN_VERSION_base(4,8,0))
+    return a = Reverse (return a)
+    {-# INLINE return #-}
+#endif
+    m >>= f = Reverse (getReverse m >>= getReverse . f)
+    {-# INLINE (>>=) #-}
+#if !(MIN_VERSION_base(4,13,0))
+    fail msg = Reverse (fail msg)
+    {-# INLINE fail #-}
+#endif
+
+#if MIN_VERSION_base(4,9,0)
+instance (Fail.MonadFail m) => Fail.MonadFail (Reverse m) where
+    fail msg = Reverse (Fail.fail msg)
+    {-# INLINE fail #-}
+#endif
+
+-- | Derived instance.
+instance (MonadPlus m) => MonadPlus (Reverse m) where
+    mzero = Reverse mzero
+    {-# INLINE mzero #-}
+    Reverse x `mplus` Reverse y = Reverse (x `mplus` y)
+    {-# INLINE mplus #-}
+
 -- | Fold from right to left.
 instance (Foldable f) => Foldable (Reverse f) where
     foldMap f (Reverse t) = getDual (foldMap (Dual . f) t)
@@ -91,12 +138,26 @@
     {-# INLINE foldr1 #-}
     foldl1 f (Reverse t) = foldr1 (flip f) t
     {-# INLINE foldl1 #-}
+#if MIN_VERSION_base(4,8,0)
+    null (Reverse t) = null t
+    length (Reverse t) = length t
+#endif
 
+#if MIN_VERSION_base(4,18,0)
+-- | Fold from right to left.
+instance (Foldable1 f) => Foldable1 (Reverse f) where
+    foldMap1 f (Reverse t) = getDual (foldMap1 (Dual . f) t)
+#endif
+
 -- | Traverse from right to left.
 instance (Traversable f) => Traversable (Reverse f) where
     traverse f (Reverse t) =
         fmap Reverse . forwards $ traverse (Backwards . f) t
     {-# INLINE traverse #-}
-    sequenceA (Reverse t) =
-        fmap Reverse . forwards $ sequenceA (fmap Backwards t)
-    {-# INLINE sequenceA #-}
+
+#if MIN_VERSION_base(4,12,0)
+-- | Derived instance.
+instance (Contravariant f) => Contravariant (Reverse f) where
+    contramap f = Reverse . contramap f . getReverse
+    {-# INLINE contramap #-}
+#endif
diff --git a/changelog b/changelog
--- a/changelog
+++ b/changelog
@@ -1,5 +1,88 @@
 -*-change-log-*-
 
+0.6.3.0 Ross Paterson <R.Paterson@city.ac.uk> Jan 2026
+	* Add Control.Monad.Trans.Except.onE
+	* Add strictToLazyState and lazyToStrictStateT
+
+0.6.2.0 Ross Paterson <R.Paterson@city.ac.uk> Apr 2025
+	* Redefine runAccumT, runExceptT and runSelectT as fields
+	* Document strictness of some transformers
+
+0.6.1.2 Ross Paterson <R.Paterson@city.ac.uk> Sep 2024
+	* Portability fixes for MicroHs
+	* Include image files in the bundle
+	* Expand ExceptT documentation
+
+0.6.1.1 Ross Paterson <R.Paterson@city.ac.uk> Aug 2023
+	* Additions to documentation, especially of AccumT.
+
+0.6.1.0 Ross Paterson <R.Paterson@city.ac.uk> Feb 2023
+	* Add instances of Foldable1 (class added to base-4.18)
+	* Add modifyM to StateT transformers
+
+0.6.0.6 Ross Paterson <R.Paterson@city.ac.uk> Jan 2023
+	* Fix for GHC 8.6
+
+0.6.0.5 Ross Paterson <R.Paterson@city.ac.uk> Jan 2023
+	* Revert to allowing MonadTrans constraint with GHC >= 8.6
+
+0.6.0.4 Ross Paterson <R.Paterson@city.ac.uk> Feb 2022
+	* Restrict deriving (Generic) to GHC >= 7.4
+
+0.6.0.3 Ross Paterson <R.Paterson@city.ac.uk> Feb 2022
+	* Restrict MonadTrans constraint to GHC >= 8.8
+
+0.6.0.2 Ross Paterson <R.Paterson@city.ac.uk> Jul 2021
+	* Further backward compatability fix
+
+0.6.0.1 Ross Paterson <R.Paterson@city.ac.uk> Jul 2021
+	* Backward compatability fixes
+
+0.6.0.0 Ross Paterson <R.Paterson@city.ac.uk> Jul 2021
+	* Added quantified constraint to MonadTrans (for GHC >= 8.6)
+	* Added Generic and Data instances
+	* Added handleE, tryE and finallyE to Control.Monad.Trans.Except
+	* Added hoistMaybe to Control.Monad.Trans.Maybe
+	* Added Generic and Data instances
+	* Added pass-throughs to instances for Backwards
+	* Made Lift's <*> lazier
+	* Remove long-deprecated selectToCont
+	* Remove long-deprecated Control.Monad.Trans.Error
+	* Remove long-deprecated Control.Monad.Trans.List
+
+0.5.6.2 Ross Paterson <R.Paterson@city.ac.uk> Feb 2019
+	* Further backward compatability fix
+
+0.5.6.1 Ross Paterson <R.Paterson@city.ac.uk> Feb 2019
+	* Backward compatability fix for MonadFix ListT instance
+
+0.5.6.0 Ross Paterson <R.Paterson@city.ac.uk> Feb 2019
+	* Generalized type of except
+	* Added Control.Monad.Trans.Writer.CPS and Control.Monad.Trans.RWS.CPS
+	* Added Contravariant instances
+	* Added MonadFix instance for ListT
+
+0.5.5.0 Ross Paterson <R.Paterson@city.ac.uk> Oct 2017
+	* Added mapSelect and mapSelectT
+	* Renamed selectToCont to selectToContT for consistency
+	* Defined explicit method definitions to fix space leaks
+	* Added missing Semigroup instance to `Constant` functor
+
+0.5.4.0 Ross Paterson <R.Paterson@city.ac.uk> Feb 2017
+	* Migrate Bifoldable and Bitraversable instances for Constant
+
+0.5.3.1 Ross Paterson <R.Paterson@city.ac.uk> Feb 2017
+	* Fixed for pre-AMP environments
+
+0.5.3.0 Ross Paterson <R.Paterson@city.ac.uk> Feb 2017
+	* Added AccumT and SelectT monad transformers
+	* Deprecated ListT
+	* Added Monad (and related) instances for Reverse
+	* Added elimLift and eitherToErrors
+	* Added specialized definitions of several methods for efficiency
+	* Removed specialized definition of sequenceA for Reverse
+	* Backported Eq1/Ord1/Read1/Show1 instances for Proxy
+
 0.5.2.0 Ross Paterson <R.Paterson@city.ac.uk> Feb 2016
 	* Re-added orphan instances for Either to deprecated module
 	* Added lots of INLINE pragmas
diff --git a/images/bind-AccumT.svg b/images/bind-AccumT.svg
new file mode 100644
--- /dev/null
+++ b/images/bind-AccumT.svg
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
+ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg width="390" height="180"
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+
+<defs>
+  <marker id="arrow" viewBox="0 0 10 10" refX="5" refY="5"
+        markerWidth="5" markerHeight="5"
+        orient="auto-start-reverse">
+      <path d="M 0 0 L 10 5 L 0 10 z" />
+  </marker>
+  <marker id="extra-arrow" viewBox="0 0 10 10" refX="5" refY="5"
+        markerWidth="5" markerHeight="5"
+        orient="auto-start-reverse">
+      <path fill="#44f" d="M 0 0 L 10 5 L 0 10 z" />
+  </marker>
+  <style type="text/css">
+    line.arrow {
+        fill: none; stroke: black; stroke-width: 4;
+        marker-end: url(#arrow);
+    }
+    circle.action {
+        fill: #f8ddbb; stroke: black; stroke-width: 4;
+    }
+    text.action {
+        fill: black; stroke: none;
+        font-family: sans-serif; font-size: 35px;
+        dominant-baseline: central; text-anchor: middle;
+    }
+    .extra {
+        fill: none; stroke: #44f; stroke-width: 3;
+        marker-end: url(#extra-arrow);
+    }
+    circle.mappend {
+        fill: none; stroke: #44f; stroke-width: 3;
+    }
+    text.mappend {
+        fill: #44f; stroke: none;
+        font-family: sans-serif; font-size: 26px;
+        dominant-baseline: central; text-anchor: middle;
+    }
+  </style>
+</defs>
+<g transform="scale(0.6) translate(50,50)">
+  <path class="extra" d="M 0,0 L 80,0 A 20 20 0 0 1 100,20 L 100,52"/>
+  <path class="extra" d="M 80,0 L 225,0"/>
+  <circle class="mappend" cx="250" cy="0" r="20"/>
+  <text class="mappend" x="250" y="0">&lt;&gt;</text>
+  <path class="extra" d="M 270,0 L 380,0 A 20 20 0 0 1 400,20 L 400,52"/>
+  <path class="extra" d="M 230,200 A 20 20 0 0 0 250,180 L 250,27"/>
+  <path class="extra" d="M 100,140 L 100,180 A 20 20 0 0 0 120,200 L 373,200"/>
+  <circle class="mappend" cx="400" cy="200" r="20"/>
+  <text class="mappend" x="400" y="200">&lt;&gt;</text>
+  <path class="extra" d="M 400,140 L 400,173"/>
+  <path class="extra" d="M 420,200 L 550,200"/>
+  <text class="mappend" x="15" y="-20">w</text>
+
+  <line class="arrow" x1="140" y1="100" x2="350" y2="100"/>
+  <line class="arrow" x1="440" y1="100" x2="550" y2="100"/>
+  <circle class="action" cx="100" cy="100" r="40"/>
+  <text class="action" x="100" y="100">m</text>
+  <circle class="action" cx="400" cy="100" r="40"/>
+  <text class="action" x="400" y="100">k</text>
+</g>
+</svg>
diff --git a/images/bind-ReaderT.svg b/images/bind-ReaderT.svg
new file mode 100644
--- /dev/null
+++ b/images/bind-ReaderT.svg
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
+ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg width="390" height="150"
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+
+<defs>
+  <marker id="arrow" viewBox="0 0 10 10" refX="5" refY="5"
+        markerWidth="5" markerHeight="5"
+        orient="auto-start-reverse">
+      <path d="M 0 0 L 10 5 L 0 10 z" />
+  </marker>
+  <marker id="extra-arrow" viewBox="0 0 10 10" refX="5" refY="5"
+        markerWidth="5" markerHeight="5"
+        orient="auto-start-reverse">
+      <path fill="#44f" d="M 0 0 L 10 5 L 0 10 z" />
+  </marker>
+  <style type="text/css">
+    line.arrow {
+        fill: none; stroke: black; stroke-width: 4;
+        marker-end: url(#arrow);
+    }
+    circle.action {
+        fill: #f8ddbb; stroke: black; stroke-width: 4;
+    }
+    text.action {
+        fill: black; stroke: none;
+        font-family: sans-serif; font-size: 35px;
+        dominant-baseline: central; text-anchor: middle;
+    }
+    .extra {
+        fill: none; stroke: #44f; stroke-width: 3;
+        marker-end: url(#extra-arrow);
+    }
+    circle.mappend {
+        fill: none; stroke: #44f; stroke-width: 3;
+    }
+    text.mappend {
+        fill: #44f; stroke: none;
+        font-family: sans-serif; font-size: 26px;
+        dominant-baseline: central; text-anchor: middle;
+    }
+  </style>
+</defs>
+<g transform="scale(0.6) translate(50,50)">
+  <path class="extra" d="M 0,0 L 80,0 A 20 20 0 0 1 100,20 L 100,52"/>
+  <path class="extra" d="M 80,0 L 380,0 A 20 20 0 0 1 400,20 L 400,52"/>
+  <text class="mappend" x="15" y="-20">r</text>
+
+  <line class="arrow" x1="140" y1="100" x2="350" y2="100"/>
+  <line class="arrow" x1="440" y1="100" x2="550" y2="100"/>
+  <circle class="action" cx="100" cy="100" r="40"/>
+  <text class="action" x="100" y="100">m</text>
+  <circle class="action" cx="400" cy="100" r="40"/>
+  <text class="action" x="400" y="100">k</text>
+</g>
+</svg>
diff --git a/images/bind-WriterT.svg b/images/bind-WriterT.svg
new file mode 100644
--- /dev/null
+++ b/images/bind-WriterT.svg
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
+ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg width="360" height="150"
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+
+<defs>
+  <marker id="arrow" viewBox="0 0 10 10" refX="5" refY="5"
+        markerWidth="5" markerHeight="5"
+        orient="auto-start-reverse">
+      <path d="M 0 0 L 10 5 L 0 10 z" />
+  </marker>
+  <marker id="extra-arrow" viewBox="0 0 10 10" refX="5" refY="5"
+        markerWidth="5" markerHeight="5"
+        orient="auto-start-reverse">
+      <path fill="#44f" d="M 0 0 L 10 5 L 0 10 z" />
+  </marker>
+  <style type="text/css">
+    line.arrow {
+        fill: none; stroke: black; stroke-width: 4;
+        marker-end: url(#arrow);
+    }
+    circle.action {
+        fill: #f8ddbb; stroke: black; stroke-width: 4;
+    }
+    text.action {
+        fill: black; stroke: none;
+        font-family: sans-serif; font-size: 35px;
+        dominant-baseline: central; text-anchor: middle;
+    }
+    .extra {
+        fill: none; stroke: #44f; stroke-width: 3;
+        marker-end: url(#extra-arrow);
+    }
+    circle.mappend {
+        fill: none; stroke: #44f; stroke-width: 3;
+    }
+    text.mappend {
+        fill: #44f; stroke: none;
+        font-family: sans-serif; font-size: 26px;
+        dominant-baseline: central; text-anchor: middle;
+    }
+  </style>
+</defs>
+<g transform="scale(0.6)">
+  <path class="extra" d="M 100,140 L 100,180 A 20 20 0 0 0 120,200 L 373,200"/>
+  <circle class="mappend" cx="400" cy="200" r="20"/>
+  <text class="mappend" x="400" y="200">&lt;&gt;</text>
+  <path class="extra" d="M 400,140 L 400,173"/>
+  <path class="extra" d="M 420,200 L 550,200"/>
+  <text class="mappend" x="520" y="180">w</text>
+
+  <line class="arrow" x1="140" y1="100" x2="350" y2="100"/>
+  <line class="arrow" x1="440" y1="100" x2="550" y2="100"/>
+  <circle class="action" cx="100" cy="100" r="40"/>
+  <text class="action" x="100" y="100">m</text>
+  <circle class="action" cx="400" cy="100" r="40"/>
+  <text class="action" x="400" y="100">k</text>
+</g>
+</svg>
diff --git a/legacy/pre709/Data/Functor/Identity.hs b/legacy/pre709/Data/Functor/Identity.hs
--- a/legacy/pre709/Data/Functor/Identity.hs
+++ b/legacy/pre709/Data/Functor/Identity.hs
@@ -13,6 +13,10 @@
 {-# LANGUAGE AutoDeriveTypeable #-}
 {-# LANGUAGE DataKinds #-}
 #endif
+#if MIN_VERSION_base(4,7,0)
+-- We need to implement bitSize for the Bits instance, but it's deprecated.
+{-# OPTIONS_GHC -fno-warn-deprecations #-}
+#endif
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Data.Functor.Identity
@@ -41,20 +45,23 @@
     Identity(..),
   ) where
 
+import Data.Bits
 import Control.Applicative
+import Control.Arrow (Arrow((***)))
 import Control.Monad.Fix
 #if MIN_VERSION_base(4,4,0)
 import Control.Monad.Zip (MonadZip(mzipWith, munzip))
 #endif
 import Data.Foldable (Foldable(foldMap))
 import Data.Monoid (Monoid(mempty, mappend))
+import Data.String (IsString(fromString))
 import Data.Traversable (Traversable(traverse))
 #if __GLASGOW_HASKELL__ >= 700
 import Data.Data
 #endif
 import Data.Ix (Ix(..))
 import Foreign (Storable(..), castPtr)
-#if __GLASGOW_HASKELL__ >= 702
+#if __GLASGOW_HASKELL__ >= 704
 import GHC.Generics
 #endif
 
@@ -64,7 +71,7 @@
 #if __GLASGOW_HASKELL__ >= 700
              , Data, Typeable
 #endif
-#if __GLASGOW_HASKELL__ >= 702
+#if __GLASGOW_HASKELL__ >= 704
              , Generic
 #endif
 #if __GLASGOW_HASKELL__ >= 706
@@ -72,6 +79,33 @@
 #endif
              )
 
+instance (Bits a) => Bits (Identity a) where
+    Identity x .&. Identity y     = Identity (x .&. y)
+    Identity x .|. Identity y     = Identity (x .|. y)
+    xor (Identity x) (Identity y) = Identity (xor x y)
+    complement   (Identity x)     = Identity (complement x)
+    shift        (Identity x) i   = Identity (shift    x i)
+    rotate       (Identity x) i   = Identity (rotate   x i)
+    setBit       (Identity x) i   = Identity (setBit   x i)
+    clearBit     (Identity x) i   = Identity (clearBit x i)
+    shiftL       (Identity x) i   = Identity (shiftL   x i)
+    shiftR       (Identity x) i   = Identity (shiftR   x i)
+    rotateL      (Identity x) i   = Identity (rotateL  x i)
+    rotateR      (Identity x) i   = Identity (rotateR  x i)
+    testBit      (Identity x) i   = testBit x i
+    bitSize      (Identity x)     = bitSize x
+    isSigned     (Identity x)     = isSigned x
+    bit i                         = Identity (bit i)
+#if MIN_VERSION_base(4,5,0)
+    unsafeShiftL (Identity x) i   = Identity (unsafeShiftL x i)
+    unsafeShiftR (Identity x) i   = Identity (unsafeShiftR x i)
+    popCount     (Identity x)     = popCount x
+#endif
+#if MIN_VERSION_base(4,7,0)
+    zeroBits                      = Identity zeroBits
+    bitSizeMaybe (Identity x)     = bitSizeMaybe x
+#endif
+
 instance (Bounded a) => Bounded (Identity a) where
     minBound = Identity minBound
     maxBound = Identity maxBound
@@ -87,27 +121,93 @@
     enumFromThenTo (Identity x) (Identity y) (Identity z) =
         map Identity (enumFromThenTo x y z)
 
+#if MIN_VERSION_base(4,7,0)
+instance (FiniteBits a) => FiniteBits (Identity a) where
+    finiteBitSize (Identity x) = finiteBitSize x
+#endif
+
+instance (Floating a) => Floating (Identity a) where
+    pi                                = Identity pi
+    exp   (Identity x)                = Identity (exp x)
+    log   (Identity x)                = Identity (log x)
+    sqrt  (Identity x)                = Identity (sqrt x)
+    sin   (Identity x)                = Identity (sin x)
+    cos   (Identity x)                = Identity (cos x)
+    tan   (Identity x)                = Identity (tan x)
+    asin  (Identity x)                = Identity (asin x)
+    acos  (Identity x)                = Identity (acos x)
+    atan  (Identity x)                = Identity (atan x)
+    sinh  (Identity x)                = Identity (sinh x)
+    cosh  (Identity x)                = Identity (cosh x)
+    tanh  (Identity x)                = Identity (tanh x)
+    asinh (Identity x)                = Identity (asinh x)
+    acosh (Identity x)                = Identity (acosh x)
+    atanh (Identity x)                = Identity (atanh x)
+    Identity x ** Identity y          = Identity (x ** y)
+    logBase (Identity x) (Identity y) = Identity (logBase x y)
+
+instance (Fractional a) => Fractional (Identity a) where
+    Identity x / Identity y = Identity (x / y)
+    recip (Identity x)      = Identity (recip x)
+    fromRational r          = Identity (fromRational r)
+
+instance (IsString a) => IsString (Identity a) where
+    fromString s = Identity (fromString s)
+
 instance (Ix a) => Ix (Identity a) where
     range     (Identity x, Identity y) = map Identity (range (x, y))
     index     (Identity x, Identity y) (Identity i) = index     (x, y) i
     inRange   (Identity x, Identity y) (Identity e) = inRange   (x, y) e
     rangeSize (Identity x, Identity y) = rangeSize (x, y)
 
+instance (Integral a) => Integral (Identity a) where
+    quot    (Identity x) (Identity y) = Identity (quot x y)
+    rem     (Identity x) (Identity y) = Identity (rem  x y)
+    div     (Identity x) (Identity y) = Identity (div  x y)
+    mod     (Identity x) (Identity y) = Identity (mod  x y)
+    quotRem (Identity x) (Identity y) = (Identity *** Identity) (quotRem x y)
+    divMod  (Identity x) (Identity y) = (Identity *** Identity) (divMod  x y)
+    toInteger (Identity x)            = toInteger x
+
 instance (Monoid a) => Monoid (Identity a) where
     mempty = Identity mempty
     mappend (Identity x) (Identity y) = Identity (mappend x y)
 
--- These instances would be equivalent to the derived instances of the
--- newtype if the field were removed.
+instance (Num a) => Num (Identity a) where
+    Identity x + Identity y = Identity (x + y)
+    Identity x - Identity y = Identity (x - y)
+    Identity x * Identity y = Identity (x * y)
+    negate (Identity x)     = Identity (negate x)
+    abs    (Identity x)     = Identity (abs    x)
+    signum (Identity x)     = Identity (signum x)
+    fromInteger n           = Identity (fromInteger n)
 
-instance (Read a) => Read (Identity a) where
-    readsPrec d = readParen (d > 10) $ \ r ->
-        [(Identity x,t) | ("Identity",s) <- lex r, (x,t) <- readsPrec 11 s]
+instance (Real a) => Real (Identity a) where
+    toRational (Identity x) = toRational x
 
-instance (Show a) => Show (Identity a) where
-    showsPrec d (Identity x) = showParen (d > 10) $
-        showString "Identity " . showsPrec 11 x
+instance (RealFloat a) => RealFloat (Identity a) where
+    floatRadix     (Identity x)     = floatRadix     x
+    floatDigits    (Identity x)     = floatDigits    x
+    floatRange     (Identity x)     = floatRange     x
+    decodeFloat    (Identity x)     = decodeFloat    x
+    exponent       (Identity x)     = exponent       x
+    isNaN          (Identity x)     = isNaN          x
+    isInfinite     (Identity x)     = isInfinite     x
+    isDenormalized (Identity x)     = isDenormalized x
+    isNegativeZero (Identity x)     = isNegativeZero x
+    isIEEE         (Identity x)     = isIEEE         x
+    significand    (Identity x)     = significand (Identity x)
+    scaleFloat s   (Identity x)     = Identity (scaleFloat s x)
+    encodeFloat m n                 = Identity (encodeFloat m n)
+    atan2 (Identity x) (Identity y) = Identity (atan2 x y)
 
+instance (RealFrac a) => RealFrac (Identity a) where
+    properFraction (Identity x) = (id *** Identity) (properFraction x)
+    truncate       (Identity x) = truncate x
+    round          (Identity x) = round    x
+    ceiling        (Identity x) = ceiling  x
+    floor          (Identity x) = floor    x
+
 instance (Storable a) => Storable (Identity a) where
     sizeOf    (Identity x)       = sizeOf x
     alignment (Identity x)       = alignment x
@@ -117,6 +217,17 @@
     pokeByteOff p i (Identity x) = pokeByteOff p i x
     peek p                       = fmap runIdentity (peek (castPtr p))
     poke p (Identity x)          = poke (castPtr p) x
+
+-- These instances would be equivalent to the derived instances of the
+-- newtype if the field were removed.
+
+instance (Read a) => Read (Identity a) where
+    readsPrec d = readParen (d > 10) $ \ r ->
+        [(Identity x,t) | ("Identity",s) <- lex r, (x,t) <- readsPrec 11 s]
+
+instance (Show a) => Show (Identity a) where
+    showsPrec d (Identity x) = showParen (d > 10) $
+        showString "Identity " . showsPrec 11 x
 
 -- ---------------------------------------------------------------------------
 -- Identity instances for Functor and Monad
diff --git a/legacy/pre711/Data/Functor/Classes.hs b/legacy/pre711/Data/Functor/Classes.hs
--- a/legacy/pre711/Data/Functor/Classes.hs
+++ b/legacy/pre711/Data/Functor/Classes.hs
@@ -69,6 +69,9 @@
 import Control.Applicative (Const(Const))
 import Data.Functor.Identity (Identity(Identity))
 import Data.Monoid (mappend)
+#if MIN_VERSION_base(4,7,0)
+import Data.Proxy (Proxy(Proxy))
+#endif
 #if __GLASGOW_HASKELL__ >= 708
 import Data.Typeable
 #endif
@@ -357,6 +360,21 @@
 
 instance (Show a) => Show1 (Either a) where
     liftShowsPrec = liftShowsPrec2 showsPrec showList
+
+#if MIN_VERSION_base(4,7,0)
+instance Eq1 Proxy where
+    liftEq _ _ _ = True
+
+instance Ord1 Proxy where
+    liftCompare _ _ _ = EQ
+
+instance Show1 Proxy where
+    liftShowsPrec _ _ _ _ = showString "Proxy"
+
+instance Read1 Proxy where
+    liftReadsPrec _ _ d =
+        readParen (d > 10) (\r -> [(Proxy, s) | ("Proxy",s) <- lex r ])
+#endif
 
 -- Instances for other functors defined in the base package
 
diff --git a/legacy/pre711/Data/Functor/Compose.hs b/legacy/pre711/Data/Functor/Compose.hs
--- a/legacy/pre711/Data/Functor/Compose.hs
+++ b/legacy/pre711/Data/Functor/Compose.hs
@@ -35,6 +35,9 @@
   ) where
 
 import Data.Functor.Classes
+#if MIN_VERSION_base(4,12,0)
+import Data.Functor.Contravariant
+#endif
 
 import Control.Applicative
 #if __GLASGOW_HASKELL__ >= 708
@@ -42,7 +45,7 @@
 #endif
 import Data.Foldable (Foldable(foldMap))
 import Data.Traversable (Traversable(traverse))
-#if __GLASGOW_HASKELL__ >= 702
+#if __GLASGOW_HASKELL__ >= 704
 import GHC.Generics
 #endif
 
@@ -53,7 +56,7 @@
 -- but the composition of monads is not always a monad.
 newtype Compose f g a = Compose { getCompose :: f (g a) }
 
-#if __GLASGOW_HASKELL__ >= 702
+#if __GLASGOW_HASKELL__ >= 704
 deriving instance Generic (Compose f g a)
 
 instance Functor f => Generic1 (Compose f g) where
@@ -144,3 +147,8 @@
 instance (Alternative f, Applicative g) => Alternative (Compose f g) where
     empty = Compose empty
     Compose x <|> Compose y = Compose (x <|> y)
+
+#if MIN_VERSION_base(4,12,0)
+instance (Functor f, Contravariant g) => Contravariant (Compose f g) where
+    contramap f (Compose fga) = Compose (fmap (contramap f) fga)
+#endif
diff --git a/legacy/pre711/Data/Functor/Product.hs b/legacy/pre711/Data/Functor/Product.hs
--- a/legacy/pre711/Data/Functor/Product.hs
+++ b/legacy/pre711/Data/Functor/Product.hs
@@ -45,16 +45,19 @@
 #endif
 import Data.Foldable (Foldable(foldMap))
 import Data.Functor.Classes
+#if MIN_VERSION_base(4,12,0)
+import Data.Functor.Contravariant
+#endif
 import Data.Monoid (mappend)
 import Data.Traversable (Traversable(traverse))
-#if __GLASGOW_HASKELL__ >= 702
+#if __GLASGOW_HASKELL__ >= 704
 import GHC.Generics
 #endif
 
 -- | Lifted product of functors.
 data Product f g a = Pair (f a) (g a)
 
-#if __GLASGOW_HASKELL__ >= 702
+#if __GLASGOW_HASKELL__ >= 704
 deriving instance Generic (Product f g a)
 
 instance Generic1 (Product f g) where
@@ -145,4 +148,9 @@
 #if MIN_VERSION_base(4,4,0)
 instance (MonadZip f, MonadZip g) => MonadZip (Product f g) where
     mzipWith f (Pair x1 y1) (Pair x2 y2) = Pair (mzipWith f x1 x2) (mzipWith f y1 y2)
+#endif
+
+#if MIN_VERSION_base(4,12,0)
+instance (Contravariant f, Contravariant g) => Contravariant (Product f g) where
+    contramap f (Pair a b) = Pair (contramap f a) (contramap f b)
 #endif
diff --git a/legacy/pre711/Data/Functor/Sum.hs b/legacy/pre711/Data/Functor/Sum.hs
--- a/legacy/pre711/Data/Functor/Sum.hs
+++ b/legacy/pre711/Data/Functor/Sum.hs
@@ -40,16 +40,19 @@
 #endif
 import Data.Foldable (Foldable(foldMap))
 import Data.Functor.Classes
+#if MIN_VERSION_base(4,12,0)
+import Data.Functor.Contravariant
+#endif
 import Data.Monoid (mappend)
 import Data.Traversable (Traversable(traverse))
-#if __GLASGOW_HASKELL__ >= 702
+#if __GLASGOW_HASKELL__ >= 704
 import GHC.Generics
 #endif
 
 -- | Lifted sum of functors.
 data Sum f g a = InL (f a) | InR (g a)
 
-#if __GLASGOW_HASKELL__ >= 702
+#if __GLASGOW_HASKELL__ >= 704
 deriving instance Generic (Sum f g a)
 
 instance Generic1 (Sum f g) where
@@ -125,3 +128,9 @@
 instance (Traversable f, Traversable g) => Traversable (Sum f g) where
     traverse f (InL x) = InL <$> traverse f x
     traverse f (InR y) = InR <$> traverse f y
+
+#if MIN_VERSION_base(4,12,0)
+instance (Contravariant f, Contravariant g) => Contravariant (Sum f g) where
+    contramap f (InL xs) = InL (contramap f xs)
+    contramap f (InR ys) = InR (contramap f ys)
+#endif
diff --git a/transformers.cabal b/transformers.cabal
--- a/transformers.cabal
+++ b/transformers.cabal
@@ -1,5 +1,5 @@
 name:         transformers
-version:      0.5.2.0
+version:      0.6.3.0
 license:      BSD3
 license-file: LICENSE
 author:       Andy Gill, Ross Paterson
@@ -9,7 +9,9 @@
 synopsis:     Concrete functor and monad transformers
 description:
     A portable library of functor and monad transformers, inspired by
-    the paper \"Functional Programming with Overloading and Higher-Order
+    the paper
+    .
+    * \"Functional Programming with Overloading and Higher-Order
     Polymorphism\", by Mark P Jones,
     in /Advanced School of Functional Programming/, 1995
     (<http://web.cecs.pdx.edu/~mpj/pubs/springschool.html>).
@@ -17,7 +19,6 @@
     This package contains:
     .
     * the monad transformer class (in "Control.Monad.Trans.Class")
-      and IO monad class (in "Control.Monad.IO.Class")
     .
     * concrete functor and monad transformers, each with associated
       operations and functions to lift operations associated with other
@@ -30,24 +31,28 @@
     the @mtl@ or @monads-tf@ packages, which automatically lift operations
     introduced by monad transformers through other transformers.
 build-type: Simple
-extra-source-files:
+extra-doc-files:
     changelog
-cabal-version: >= 1.6
+    images/bind-AccumT.svg
+    images/bind-ReaderT.svg
+    images/bind-WriterT.svg
+cabal-version: 1.18
 
 source-repository head
   type: darcs
   location: http://hub.darcs.net/ross/transformers
 
 library
+  default-language: Haskell2010
   build-depends: base >= 2 && < 6
   hs-source-dirs: .
-  if !impl(ghc>=7.9)
+  if impl(ghc<7.9)
     -- Data.Functor.Identity was moved into base-4.8.0.0 (GHC 7.10)
     -- see also https://ghc.haskell.org/trac/ghc/ticket/9664
     -- NB: using impl(ghc>=7.9) instead of fragile Cabal flags
     hs-source-dirs: legacy/pre709
     exposed-modules: Data.Functor.Identity
-  if !impl(ghc>=7.11)
+  if impl(ghc<7.11)
     -- modules moved into base-4.9.0 (GHC 8.0)
     -- see https://ghc.haskell.org/trac/ghc/ticket/10773
     -- see https://ghc.haskell.org/trac/ghc/ticket/11135
@@ -60,26 +65,28 @@
       Data.Functor.Sum
   if impl(ghc>=7.2 && <7.5)
     -- Prior to GHC 7.5, GHC.Generics lived in ghc-prim
-    build-depends: ghc-prim
+    build-depends: ghc-prim < 0.3
   exposed-modules:
     Control.Applicative.Backwards
     Control.Applicative.Lift
     Control.Monad.Signatures
+    Control.Monad.Trans.Accum
     Control.Monad.Trans.Class
     Control.Monad.Trans.Cont
     Control.Monad.Trans.Except
-    Control.Monad.Trans.Error
     Control.Monad.Trans.Identity
-    Control.Monad.Trans.List
     Control.Monad.Trans.Maybe
     Control.Monad.Trans.Reader
     Control.Monad.Trans.RWS
+    Control.Monad.Trans.RWS.CPS
     Control.Monad.Trans.RWS.Lazy
     Control.Monad.Trans.RWS.Strict
+    Control.Monad.Trans.Select
     Control.Monad.Trans.State
     Control.Monad.Trans.State.Lazy
     Control.Monad.Trans.State.Strict
     Control.Monad.Trans.Writer
+    Control.Monad.Trans.Writer.CPS
     Control.Monad.Trans.Writer.Lazy
     Control.Monad.Trans.Writer.Strict
     Data.Functor.Constant
