diff --git a/Control/Applicative/Backwards.hs b/Control/Applicative/Backwards.hs
--- a/Control/Applicative/Backwards.hs
+++ b/Control/Applicative/Backwards.hs
@@ -28,7 +28,7 @@
 
 import Data.Functor.Classes
 
-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
@@ -89,6 +89,10 @@
     {-# 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
 
 -- | Derived instance.
 instance (Traversable f) => Traversable (Backwards f) where
diff --git a/Control/Applicative/Lift.hs b/Control/Applicative/Lift.hs
--- a/Control/Applicative/Lift.hs
+++ b/Control/Applicative/Lift.hs
@@ -23,10 +23,12 @@
     Lift(..),
     unLift,
     mapLift,
+    elimLift,
     -- * Collecting errors
     Errors,
     runErrors,
-    failure
+    failure,
+    eitherToErrors
   ) where
 
 import Data.Functor.Classes
@@ -116,6 +118,17 @@
 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",
@@ -146,3 +159,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/Trans/Accum.hs b/Control/Monad/Trans/Accum.hs
new file mode 100644
--- /dev/null
+++ b/Control/Monad/Trans/Accum.hs
@@ -0,0 +1,290 @@
+{-# LANGUAGE CPP #-}
+#if __GLASGOW_HASKELL__ >= 702
+{-# LANGUAGE Safe #-}
+#endif
+#if __GLASGOW_HASKELL__ >= 710
+{-# 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.
+--
+-- This monad transformer provides append-only accumulation
+-- during the computation. For more general access, 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(AccumT),
+    runAccumT,
+    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
+
+-- ---------------------------------------------------------------------------
+-- | An accumulation 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'.
+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.
+--
+-- The 'return' function produces the output 'mempty', while @>>=@
+-- combines the outputs of the subcomputations using 'mappend'.
+--
+-- This monad transformer is similar to both state and writer monad transformers.
+-- Thus it can be seen as
+--
+--  * a restricted append-only version of a state monad transformer or
+--
+--  * a writer monad transformer with the extra ability to read all previous output.
+newtype AccumT w m a = AccumT (w -> m (a, w))
+
+-- | Unwrap an accumulation computation.
+runAccumT :: AccumT w m a -> w -> m (a, w)
+runAccumT (AccumT f) = f
+{-# INLINE runAccumT #-}
+
+-- | 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, Monad m) => Applicative (AccumT w m) where
+    pure a  = AccumT $ const $ pure (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, MonadPlus m) => Alternative (AccumT w m) where
+    empty   = AccumT $ const mzero
+    {-# INLINE empty #-}
+    m <|> n = AccumT $ \ w -> runAccumT m w <|> runAccumT n w
+    {-# INLINE (<|>) #-}
+
+instance (Monoid w, 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 (>>=) #-}
+    fail msg = AccumT $ const (fail msg)
+    {-# INLINE fail #-}
+
+#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, 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, 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, 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.
+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
@@ -69,12 +69,13 @@
 major release they will 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
 
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
@@ -46,8 +46,9 @@
 #if MIN_VERSION_base(4,4,0)
 import Control.Monad.Zip (MonadZip(mzipWith))
 #endif
-import Data.Foldable (Foldable(foldMap))
+import Data.Foldable
 import Data.Traversable (Traversable(traverse))
+import Prelude hiding (foldr, foldr1, foldl, foldl1, null, length)
 
 -- | The trivial monad transformer, which maps a monad to an equivalent monad.
 newtype IdentityT f a = IdentityT { runIdentityT :: f a }
@@ -78,8 +79,20 @@
     {-# 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
 
 instance (Traversable f) => Traversable (IdentityT f) where
     traverse f (IdentityT a) = IdentityT <$> traverse f a
diff --git a/Control/Monad/Trans/List.hs b/Control/Monad/Trans/List.hs
--- a/Control/Monad/Trans/List.hs
+++ b/Control/Monad/Trans/List.hs
@@ -20,7 +20,8 @@
 -- which must be commutative.
 -----------------------------------------------------------------------------
 
-module Control.Monad.Trans.List (
+module Control.Monad.Trans.List
+  {-# DEPRECATED "This transformer is invalid on most monads" #-} (
     -- * The ListT monad transformer
     ListT(..),
     mapListT,
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
@@ -63,6 +63,9 @@
 #if MIN_VERSION_base(4,4,0)
 import Control.Monad.Zip (MonadZip(mzipWith))
 #endif
+#if MIN_VERSION_base(4,2,0)
+import Data.Functor(Functor(..))
+#endif
 
 -- | The parameterizable reader monad.
 --
@@ -132,12 +135,22 @@
 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
 
 instance (Alternative m) => Alternative (ReaderT r m) where
     empty   = liftReaderT empty
@@ -154,6 +167,8 @@
         a <- runReaderT m r
         runReaderT (k a) r
     {-# INLINE (>>=) #-}
+    m >> k = ReaderT $ \ r -> runReaderT m r >> runReaderT k r
+    {-# INLINE (>>) #-}
     fail msg = lift (fail msg)
     {-# INLINE fail #-}
 
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,133 @@
+{-# LANGUAGE CPP #-}
+#if __GLASGOW_HASKELL__ >= 702
+{-# LANGUAGE Safe #-}
+#endif
+#if __GLASGOW_HASKELL__ >= 706
+{-# LANGUAGE PolyKinds #-}
+#endif
+#if __GLASGOW_HASKELL__ >= 710
+{-# 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,
+    -- * The SelectT monad transformer
+    SelectT(SelectT),
+    runSelectT,
+    selectToCont,
+    ) 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
+
+-- | Selection monad.
+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 #-}
+
+-- | Selection monad transformer.
+--
+-- 'SelectT' is not a functor on the category of monads, and many operations
+-- cannot be lifted through it.
+newtype SelectT r m a = SelectT ((a -> m r) -> m a)
+
+-- | Runs a @SelectT@ computation with a function for evaluating answers
+-- to select a particular answer.  (The inverse of 'select'.)
+runSelectT :: SelectT r m a -> (a -> m r) -> m a
+runSelectT (SelectT g) = g
+{-# INLINE runSelectT #-}
+
+instance (Functor m) => Functor (SelectT r m) where
+    fmap f (SelectT g) = SelectT (fmap f . g . (. f))
+    {-# INLINE fmap #-}
+
+instance (Monad m) => Applicative (SelectT r m) where
+    pure = lift . pure
+    {-# INLINE pure #-}
+    SelectT gf <*> SelectT gx = SelectT $ \ k -> do
+        let h f = liftM f (gx (k . f))
+        f <- gf ((>>= k) . h)
+        h f
+    {-# INLINE (<*>) #-}
+
+instance (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 = pure
+    {-# 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.
+selectToCont :: (Monad m) => SelectT r m a -> ContT r m a
+selectToCont (SelectT g) = ContT $ \ k -> g k >>= k
+{-# INLINE selectToCont #-}
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
@@ -206,6 +206,7 @@
         ~(x, s'') <- mx s'
         return (f x, s'')
     {-# INLINE (<*>) #-}
+    (*>) = (>>)
 
 instance (Functor m, MonadPlus m) => Alternative (StateT s m) where
     empty = StateT $ \ _ -> mzero
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
@@ -203,6 +203,7 @@
         (x, s'') <- mx s'
         return (f x, s'')
     {-# INLINE (<*>) #-}
+    (*>) = (>>)
 
 instance (Functor m, MonadPlus m) => Alternative (StateT s m) where
     empty = StateT $ \ _ -> mzero
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
@@ -64,9 +64,10 @@
 #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
 import Data.Traversable (Traversable(traverse))
+import Prelude hiding (null, length)
 
 -- ---------------------------------------------------------------------------
 -- | A writer monad parameterized by the type @w@ of output to accumulate.
@@ -167,6 +168,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
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
@@ -67,9 +67,10 @@
 #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
 import Data.Traversable (Traversable(traverse))
+import Prelude hiding (null, length)
 
 -- ---------------------------------------------------------------------------
 -- | A writer monad parameterized by the type @w@ of output to accumulate.
@@ -170,6 +171,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
diff --git a/Data/Functor/Constant.hs b/Data/Functor/Constant.hs
--- a/Data/Functor/Constant.hs
+++ b/Data/Functor/Constant.hs
@@ -28,12 +28,13 @@
 import Data.Functor.Classes
 
 import Control.Applicative
-import Data.Foldable (Foldable(foldMap))
+import Data.Foldable
 import Data.Monoid (Monoid(..))
 import Data.Traversable (Traversable(traverse))
 #if MIN_VERSION_base(4,8,0)
 import Data.Bifunctor (Bifunctor(..))
 #endif
+import Prelude hiding (null, length)
 
 -- | Constant functor.
 newtype Constant a b = Constant { getConstant :: a }
@@ -86,6 +87,10 @@
 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)
diff --git a/Data/Functor/Reverse.hs b/Data/Functor/Reverse.hs
--- a/Data/Functor/Reverse.hs
+++ b/Data/Functor/Reverse.hs
@@ -29,8 +29,12 @@
 import Control.Applicative.Backwards
 import Data.Functor.Classes
 
-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
 import Data.Monoid
@@ -79,6 +83,28 @@
     Reverse x <|> Reverse y = Reverse (x <|> y)
     {-# INLINE (<|>) #-}
 
+-- | Derived instance.
+instance (Monad m) => Monad (Reverse m) where
+    return a = Reverse (return a)
+    {-# INLINE return #-}
+    m >>= f = Reverse (getReverse m >>= getReverse . f)
+    {-# INLINE (>>=) #-}
+    fail msg = Reverse (fail msg)
+    {-# INLINE fail #-}
+
+#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 +117,13 @@
     {-# 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
 
 -- | 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 #-}
diff --git a/changelog b/changelog
--- a/changelog
+++ b/changelog
@@ -1,5 +1,14 @@
 -*-change-log-*-
 
+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/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,13 +45,16 @@
     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
@@ -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/transformers.cabal b/transformers.cabal
--- a/transformers.cabal
+++ b/transformers.cabal
@@ -1,5 +1,5 @@
 name:         transformers
-version:      0.5.2.0
+version:      0.5.3.0
 license:      BSD3
 license-file: LICENSE
 author:       Andy Gill, Ross Paterson
@@ -17,7 +17,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
@@ -65,6 +64,7 @@
     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
@@ -76,6 +76,7 @@
     Control.Monad.Trans.RWS
     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
