diff --git a/Control/Applicative/Backwards.hs b/Control/Applicative/Backwards.hs
--- a/Control/Applicative/Backwards.hs
+++ b/Control/Applicative/Backwards.hs
@@ -10,8 +10,13 @@
 -- Making functors with an 'Applicative' instance that performs actions
 -- in the reverse order.
 
-module Control.Applicative.Backwards where
+module Control.Applicative.Backwards (
+    Backwards(..),
+    forwards,
+  ) where
 
+import Data.Functor.Classes
+
 import Prelude hiding (foldr, foldr1, foldl, foldl1)
 import Control.Applicative
 import Data.Foldable
@@ -19,7 +24,28 @@
 
 -- | The same functor, but with an 'Applicative' instance that performs
 -- actions in the reverse order.
-newtype Backwards f a = Backwards { forwards :: f a }
+newtype Backwards f a = Backwards (f a)
+
+-- | Inverse of 'Backwards'.
+forwards :: Backwards f a -> f a
+forwards (Backwards x) = x
+
+instance (Eq1 f, Eq a) => Eq (Backwards f a) where
+    Backwards x == Backwards y = eq1 x y
+
+instance (Ord1 f, Ord a) => Ord (Backwards f a) where
+    compare (Backwards x) (Backwards y) = compare1 x y
+
+instance (Read1 f, Read a) => Read (Backwards f a) where
+    readsPrec = readsData $ readsUnary1 "Backwards" Backwards
+
+instance (Show1 f, Show a) => Show (Backwards f a) where
+    showsPrec d (Backwards x) = showsUnary1 "Backwards" d x
+
+instance (Eq1 f) => Eq1 (Backwards f) where eq1 = (==)
+instance (Ord1 f) => Ord1 (Backwards f) where compare1 = compare
+instance (Read1 f) => Read1 (Backwards f) where readsPrec1 = readsPrec
+instance (Show1 f) => Show1 (Backwards f) where showsPrec1 = showsPrec
 
 -- | Derived instance.
 instance (Functor f) => Functor (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
@@ -10,21 +10,49 @@
 -- Adding a new kind of pure computation to an applicative functor.
 
 module Control.Applicative.Lift (
-    Lift(..), unLift,
+    Lift(..),
+    unLift,
     -- * Collecting errors
-    Errors, failure
+    Errors,
+    failure
   ) where
 
+import Data.Functor.Classes
+
 import Control.Applicative
 import Data.Foldable (Foldable(foldMap))
 import Data.Functor.Constant
-import Data.Monoid (Monoid(mappend))
+import Data.Monoid (Monoid(..))
 import Data.Traversable (Traversable(traverse))
 
 -- | Applicative functor formed by adding pure computations to a given
 -- applicative functor.
 data Lift f a = Pure a | Other (f a)
 
+instance (Eq1 f, Eq a) => Eq (Lift f a) where
+    Pure x1 == Pure x2 = x1 == x2
+    Other y1 == Other y2 = eq1 y1 y2
+    _ == _ = False
+
+instance (Ord1 f, Ord a) => Ord (Lift f a) where
+    compare (Pure x1) (Pure x2) = compare x1 x2
+    compare (Pure _) (Other _) = LT
+    compare (Other _) (Pure _) = GT
+    compare (Other y1) (Other y2) = compare1 y1 y2
+
+instance (Read1 f, Read a) => Read (Lift f a) where
+    readsPrec = readsData $
+        readsUnary "Pure" Pure `mappend` readsUnary1 "Other" Other
+
+instance (Show1 f, Show a) => Show (Lift f a) where
+    showsPrec d (Pure x) = showsUnary "Pure" d x
+    showsPrec d (Other y) = showsUnary1 "Other" d y
+
+instance (Eq1 f) => Eq1 (Lift f) where eq1 = (==)
+instance (Ord1 f) => Ord1 (Lift f) where compare1 = compare
+instance (Read1 f) => Read1 (Lift f) where readsPrec1 = readsPrec
+instance (Show1 f) => Show1 (Lift f) where showsPrec1 = showsPrec
+
 instance (Functor f) => Functor (Lift f) where
     fmap f (Pure x) = Pure (f x)
     fmap f (Other y) = Other (fmap f y)
@@ -46,23 +74,23 @@
     Other f <*> Other y = Other (f <*> y)
 
 -- | A combination is 'Pure' only either part is.
-instance Alternative f => Alternative (Lift f) where
+instance (Alternative f) => Alternative (Lift f) where
     empty = Other empty
     Pure x <|> _ = Pure x
     Other _ <|> Pure y = Pure y
     Other x <|> Other y = Other (x <|> y)
 
 -- | Projection to the other functor.
-unLift :: Applicative f => Lift f a -> f a
+unLift :: (Applicative f) => Lift f a -> f a
 unLift (Pure x) = pure x
 unLift (Other e) = e
 
 -- | 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 'ErrorT' from "Control.Monad.Trans.Error",
+-- unlike monads made with 'ExceptT' from "Control.Monad.Trans.Except",
 -- these computations continue after an error, collecting all the errors.
 type Errors e = Lift (Constant e)
 
 -- | Report an error.
-failure :: Monoid e => e -> Errors e a
+failure :: (Monoid e) => e -> Errors e a
 failure e = Other (Constant e)
diff --git a/Control/Monad/IO/Class.hs b/Control/Monad/IO/Class.hs
--- a/Control/Monad/IO/Class.hs
+++ b/Control/Monad/IO/Class.hs
@@ -16,8 +16,6 @@
     MonadIO(..)
   ) where
 
-import System.IO (IO)
-
 -- | Monads in which 'IO' computations may be embedded.
 -- Any monad built by applying a sequence of monad transformers to the
 -- 'IO' monad will be an instance of this class.
diff --git a/Control/Monad/Signatures.hs b/Control/Monad/Signatures.hs
new file mode 100644
--- /dev/null
+++ b/Control/Monad/Signatures.hs
@@ -0,0 +1,32 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Control.Monad.Signatures
+-- Copyright   :  (c) Ross Paterson 2012
+-- License     :  BSD-style (see the file LICENSE)
+--
+-- Maintainer  :  ross@soi.city.ac.uk
+-- Stability   :  experimental
+-- Portability :  portable
+--
+-- Signatures for monad operations that require specialized lifting.
+-----------------------------------------------------------------------------
+
+module Control.Monad.Signatures (
+    CallCC, Catch, Listen, Pass
+  ) where
+
+-- | Signature of the @callCC@ operation,
+-- introduced in "Control.Monad.Trans.Cont".
+type CallCC m a b = ((a -> m b) -> m a) -> m a
+
+-- | Signature of the @catchE@ operation,
+-- introduced in "Control.Monad.Trans.Except".
+type Catch e m a = m a -> (e -> m a) -> m a
+
+-- | Signature of the @listen@ operation,
+-- introduced in "Control.Monad.Trans.Writer".
+type Listen w m a = m a -> m (a, w)
+
+-- | Signature of the @pass@ operation,
+-- introduced in "Control.Monad.Trans.Writer".
+type Pass w m a =  m (a, w -> w) -> m a
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
@@ -9,36 +9,38 @@
 -- Stability   :  experimental
 -- Portability :  portable
 --
--- Classes for monad transformers.
+-- The class of monad transformers.
 --
 -- A monad transformer makes a new monad out of an existing monad, such
 -- that computations of the old monad may be embedded in the new one.
 -- To construct a monad with a desired set of features, one typically
--- starts with a base monad, such as @Identity@, @[]@ or 'IO', and
+-- starts with a base monad, such as 'Data.Functor.Identity.Identity', @[]@ or 'IO', and
 -- applies a sequence of monad transformers.
---
--- Most monad transformer modules include the special case of applying the
--- transformer to @Identity@.  For example, @State s@ is an abbreviation
--- for @StateT s Identity@.
---
--- Each monad transformer also comes with an operation @run@/XXX/ to
--- unwrap the transformer, exposing a computation of the inner monad.
 -----------------------------------------------------------------------------
 
 module Control.Monad.Trans.Class (
     -- * Transformer class
     MonadTrans(..)
 
+    -- * Conventions
+    -- $conventions
+
+    -- * Strict monads
+    -- $strict
+
     -- * Examples
     -- ** Parsing
     -- $example1
 
     -- ** Parsing and counting
     -- $example2
+
+    -- ** Interpreter monad
+    -- $example3
   ) where
 
 -- | The class of monad transformers.  Instances should satisfy the
--- following laws, which state that 'lift' is a transformer of monads:
+-- following laws, which state that 'lift' is a monad transformation:
 --
 -- * @'lift' . 'return' = 'return'@
 --
@@ -46,8 +48,53 @@
 
 class MonadTrans t where
     -- | Lift a computation from the argument monad to the constructed monad.
-    lift :: Monad m => m a -> t m a
+    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,
+@'Control.Monad.Trans.State.Lazy.State' s@ is an abbreviation for
+@'Control.Monad.Trans.State.Lazy.StateT' s 'Data.Functor.Identity.Identity'@.
+
+Each monad transformer also comes with an operation @run@/XXX/@T@ to
+unwrap the transformer, exposing a computation of the inner monad.
+
+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
+
+> mapStateT t :: StateT s M a -> StateT s N a
+
+Each of the monad transformers introduces relevant operations.
+In a sequence of monad transformers, most of these operations.can be
+lifted through other transformers using 'lift' or the @map@/XXX/@T@
+combinator, but a few with more complex type signatures require
+specialized lifting combinators, called @lift@/Op/.
+-}
+
+{- $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:
+
+>>> undefined >> return 2 :: Maybe Integer
+*** Exception: Prelude.undefined
+
+However the monad 'Data.Functor.Identity.Identity' is not:
+
+>>> runIdentity (undefined >> return 2)
+2
+
+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
+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
@@ -58,9 +105,8 @@
 > type Parser = StateT String []
 
 Then @Parser@ is an instance of @MonadPlus@: monadic sequencing implements
-concatenation of parsers, while @mplus@ provides choice.
-To use parsers, we need a primitive to run a constructed parser on an
-input string:
+concatenation of parsers, while @mplus@ provides choice.  To use parsers,
+we need a primitive to run a constructed parser on an input string:
 
 > runParser :: Parser a -> String -> [a]
 > runParser p s = [x | (x, "") <- runStateT p s]
@@ -76,14 +122,15 @@
 
 In this example we use the operations @get@ and @put@ from
 "Control.Monad.Trans.State", which are defined only for monads that are
-applications of @StateT@.  Alternatively one could use monad classes
-from the @mtl@ package or similar, which contain methods @get@ and @put@
-with types generalized over all suitable monads.
+applications of 'Control.Monad.Trans.State.Lazy.StateT'.  Alternatively one
+could use monad classes from the @mtl@ package or similar, which contain
+methods @get@ and @put@ with types generalized over all suitable monads.
 -}
 
 {- $example2
 
-We can define a parser that also counts by adding a @WriterT@ transformer:
+We can define a parser that also counts by adding a
+'Control.Monad.Trans.Writer.Lazy.WriterT' transformer:
 
 > import Control.Monad.Trans.Class
 > import Control.Monad.Trans.State
@@ -98,8 +145,9 @@
 > runParser :: Parser a -> String -> [(a, Int)]
 > runParser p s = [(x, n) | ((x, Sum n), "") <- runStateT (runWriterT p) s]
 
-To define @item@ parser, we need to lift the @StateT@ operations through
-the @WriterT@ transformers.
+To define the @item@ parser, we need to lift the
+'Control.Monad.Trans.State.Lazy.StateT' operations through the
+'Control.Monad.Trans.Writer.Lazy.WriterT' transformer.
 
 > item :: Parser Char
 > item = do
@@ -120,4 +168,71 @@
 > tick = tell (Sum 1)
 
 Then the parser will keep track of how many @tick@s it executes.
+-}
+
+{- $example3
+
+This example is a cut-down version of the one in
+\"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>).
+
+Suppose we want to define an interpreter that can do I\/O and has
+exceptions, an environment and a modifiable store.  We can define
+a monad that supports all these things as a stack of monad transformers:
+
+> import Control.Monad.Trans.Class
+> import Control.Monad.Trans.State
+> import qualified Control.Monad.Trans.Reader as R
+> import qualified Control.Monad.Trans.Except as E
+>
+> type InterpM = StateT Store (R.ReaderT Env (E.ExceptT Err []))
+
+for suitable types @Store@, @Env@ and @Err@.
+
+Now we would like to be able to use the operations associated with each
+of those monad transformers on @InterpM@ actions.  Since the uppermost
+monad transformer of @InterpM@ is 'Control.Monad.Trans.State.Lazy.StateT',
+it already has the state operations @get@ and @set@.
+
+The first of the 'Control.Monad.Trans.Reader.ReaderT' operations,
+'Control.Monad.Trans.Reader.ask', is a simple action, so we can lift it
+through 'Control.Monad.Trans.State.Lazy.StateT' to @InterpM@ using 'lift':
+
+> ask :: InterpM Env
+> ask = lift R.ask
+
+The other 'Control.Monad.Trans.Reader.ReaderT' operation,
+'Control.Monad.Trans.Reader.local', has a suitable type for lifting
+using 'Control.Monad.Trans.State.Lazy.mapStateT':
+
+> local :: (Env -> Env) -> InterpM a -> InterpM a
+> local f = mapStateT (R.local f)
+
+We also wish to lift the operations of 'Control.Monad.Trans.Except.ExceptT'
+through both 'Control.Monad.Trans.Reader.ReaderT' and
+'Control.Monad.Trans.State.Lazy.StateT'.  For the operation
+'Control.Monad.Trans.Except.throwE', we know @throwE e@ is a simple
+action, so we can lift it through the two monad transformers to @InterpM@
+with two 'lift's:
+
+> throwE :: Err -> InterpM a
+> throwE e = lift (lift (E.throwE e))
+
+The 'Control.Monad.Trans.Except.catchE' operation has a more
+complex type, so we need to use the special-purpose lifting function
+@liftCatch@ provided by most monad transformers.  Here we use
+the 'Control.Monad.Trans.Reader.ReaderT' version followed by the
+'Control.Monad.Trans.State.Lazy.StateT' version:
+
+> catchE :: InterpM a -> (Err -> InterpM a) -> InterpM a
+> catchE = liftCatch (R.liftCatch E.catchE)
+
+We could lift 'IO' actions to @InterpM@ using three 'lift's, but @InterpM@
+is automatically an instance of 'Control.Monad.IO.Class.MonadIO',
+so we can use 'Control.Monad.IO.Class.liftIO' instead:
+
+> putStr :: String -> InterpM ()
+> putStr s = liftIO (Prelude.putStr s)
+
 -}
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
@@ -10,6 +10,10 @@
 --
 -- Continuation monads.
 --
+-- Delimited continuation operators are taken from Kenichi Asai and Oleg
+-- Kiselyov's tutorial at CW 2011, \"Introduction to programming with
+-- shift and reset\" (<http://okmij.org/ftp/continuations/#tutorial>).
+--
 -----------------------------------------------------------------------------
 
 module Control.Monad.Trans.Cont (
@@ -17,13 +21,20 @@
     Cont,
     cont,
     runCont,
+    evalCont,
     mapCont,
     withCont,
+    -- ** Delimited continuations
+    reset, shift,
     -- * The ContT monad transformer
     ContT(..),
+    runContT,
+    evalContT,
     mapContT,
     withContT,
     callCC,
+    -- ** Delimited continuations
+    resetT, shiftT,
     -- * Lifting other operations
     liftLocal,
   ) where
@@ -33,7 +44,6 @@
 import Data.Functor.Identity
 
 import Control.Applicative
-import Control.Monad
 
 {- |
 Continuation monad.
@@ -47,19 +57,25 @@
 type Cont r = ContT r Identity
 
 -- | Construct a continuation-passing computation from a function.
--- (The inverse of 'runCont'.)
+-- (The inverse of 'runCont')
 cont :: ((a -> r) -> r) -> Cont r a
-cont f = ContT (\ k -> Identity (f (runIdentity . k)))
+cont f = ContT (\ c -> Identity (f (runIdentity . c)))
 
--- | Runs a CPS computation, returns its result after applying the final
--- continuation to it.
--- (The inverse of 'cont'.)
+-- | The result of running a CPS computation with a given final continuation.
+-- (The inverse of 'cont')
 runCont :: Cont r a	-- ^ continuation computation (@Cont@).
     -> (a -> r)		-- ^ the final continuation, which produces
 			-- the final result (often 'id').
     -> r
 runCont m k = runIdentity (runContT m (Identity . k))
 
+-- | The result of running a CPS computation with the identity as the
+-- final continuation.
+--
+-- * @'evalCont' ('return' x) = x@
+evalCont :: Cont r r -> r
+evalCont m = runIdentity (evalContT m)
+
 -- | Apply a function to transform the result of a continuation-passing
 -- computation.
 --
@@ -74,12 +90,37 @@
 withCont :: ((b -> r) -> (a -> r)) -> Cont r a -> Cont r b
 withCont f = withContT ((Identity .) . f . (runIdentity .))
 
-{- |
-The continuation monad transformer.
-Can be used to add continuation handling to other monads.
--}
-newtype ContT r m a = ContT { runContT :: (a -> m r) -> m r }
+-- | @'reset' m@ delimits the continuation of any 'shift' inside @m@.
+--
+-- * @'reset' ('return' m) = 'return' m@
+--
+reset :: Cont r r -> Cont r' r
+reset = resetT
 
+-- | @'shift' f@ captures the continuation up to the nearest enclosing
+-- 'reset' and passes it to @f@:
+--
+-- * @'reset' ('shift' f >>= k) = 'reset' (f ('evalCont' . k))@
+--
+shift :: ((a -> r) -> Cont r r) -> Cont r a
+shift f = shiftT (f . (runIdentity .))
+
+-- | The continuation monad transformer.
+-- Can be used to add continuation handling to other monads.
+newtype ContT r m a = ContT ((a -> m r) -> m r)
+
+-- | The result of running a CPS computation with a given final continuation.
+-- (The inverse of 'cont')
+runContT :: ContT r m a -> (a -> m r) -> m r
+runContT (ContT m) = m
+
+-- | The result of running a CPS computation with 'return' as the
+-- final continuation.
+--
+-- * @'evalContT' ('lift' m) = m@
+evalContT :: (Monad m) => ContT r m r -> m r
+evalContT m = runContT m return
+
 -- | Apply a function to transform the result of a continuation-passing
 -- computation.
 --
@@ -95,15 +136,15 @@
 withContT f m = ContT $ runContT m . f
 
 instance Functor (ContT r m) where
-    fmap f m = ContT $ \c -> runContT m (c . f)
+    fmap f m = ContT $ \ c -> runContT m (c . f)
 
 instance Applicative (ContT r m) where
-    pure a  = ContT ($ a)
-    f <*> v = ContT $ \ k -> runContT f $ \ g -> runContT v (k . g)
+    pure x  = ContT ($ x)
+    f <*> v = ContT $ \ c -> runContT f $ \ g -> runContT v (c . g)
 
 instance Monad (ContT r m) where
-    return a = ContT ($ a)
-    m >>= k  = ContT $ \c -> runContT m (\a -> runContT (k a) c)
+    return x = ContT ($ x)
+    m >>= k  = ContT $ \ c -> runContT m (\ x -> runContT (k x) c)
 
 instance MonadTrans (ContT r) where
     lift m = ContT (m >>=)
@@ -115,10 +156,10 @@
 -- function, passing it the current continuation.  It provides
 -- an escape continuation mechanism for use with continuation
 -- monads.  Escape continuations one allow to abort the current
--- computation and return a value immediately.  They achieve a
--- similar effect to 'Control.Monad.Trans.Error.throwError'
--- and 'Control.Monad.Trans.Error.catchError' within an
--- 'Control.Monad.Trans.Error.ErrorT' monad.  The advantage of this
+-- computation and return a value immediately.  They achieve
+-- a similar effect to 'Control.Monad.Trans.Except.throwE'
+-- and 'Control.Monad.Trans.Except.catchE' within an
+-- 'Control.Monad.Trans.Except.ExceptT' monad.  The advantage of this
 -- function over calling 'return' is that it makes the continuation
 -- explicit, allowing more flexibility and better control.
 --
@@ -127,11 +168,26 @@
 -- within its scope will escape from the computation, even if it is many
 -- layers deep within nested computations.
 callCC :: ((a -> ContT r m b) -> ContT r m a) -> ContT r m a
-callCC f = ContT $ \c -> runContT (f (\a -> ContT $ \_ -> c a)) c
+callCC f = ContT $ \ c -> runContT (f (\ x -> ContT $ \ _ -> c x)) c
 
+-- | @'resetT' m@ delimits the continuation of any 'shiftT' inside @m@.
+--
+-- * @'resetT' ('lift' m) = 'lift' m@
+--
+resetT :: (Monad m) => ContT r m r -> ContT r' m r
+resetT = lift . evalContT
+
+-- | @'shiftT' f@ captures the continuation up to the nearest enclosing
+-- 'resetT' and passes it to @f@:
+--
+-- * @'resetT' ('shiftT' f >>= k) = 'resetT' (f ('evalContT' . k))@
+--
+shiftT :: (Monad m) => ((a -> m r) -> ContT r m r) -> ContT r m a
+shiftT f = ContT (evalContT . f)
+
 -- | @'liftLocal' ask local@ yields a @local@ function for @'ContT' r m@.
-liftLocal :: Monad m => m r' -> ((r' -> r') -> m r -> m r) ->
+liftLocal :: (Monad m) => m r' -> ((r' -> r') -> m r -> m r) ->
     (r' -> r') -> ContT r m a -> ContT r m a
-liftLocal ask local f m = ContT $ \c -> do
+liftLocal ask local f m = ContT $ \ c -> do
     r <- ask
     local f (runContT m (local (const r) . c))
diff --git a/Control/Monad/Trans/Error.hs b/Control/Monad/Trans/Error.hs
--- a/Control/Monad/Trans/Error.hs
+++ b/Control/Monad/Trans/Error.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE CPP #-}
+{-# OPTIONS_GHC -fno-warn-orphans #-}
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Control.Monad.Trans.Error
@@ -21,13 +22,19 @@
 --
 -- 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 (
+module Control.Monad.Trans.Error
+  {-# DEPRECATED "Use Control.Monad.Trans.Except instead" #-} (
     -- * The ErrorT monad transformer
     Error(..),
     ErrorList(..),
     ErrorT(..),
+    runErrorT,
     mapErrorT,
     -- * Error operations
     throwError,
@@ -41,13 +48,17 @@
   ) 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
 import Control.Monad.Fix
-import Control.Monad.Instances ()
+#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))
@@ -55,8 +66,12 @@
 
 instance MonadPlus IO where
     mzero       = ioError (userError "mzero")
-    m `mplus` n = m `catchIOError` \_ -> n
+    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
@@ -81,7 +96,7 @@
     strMsg = userError
 
 -- | A string can be thrown as an error.
-instance ErrorList a => Error [a] where
+instance (ErrorList a) => Error [a] where
     strMsg = listMsg
 
 -- | Workaround so that we can have a Haskell 98 instance @'Error' 'String'@.
@@ -138,8 +153,29 @@
 --
 -- 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) }
+newtype ErrorT e m a = ErrorT (m (Either e a))
 
+instance (Eq e, Eq1 m, Eq a) => Eq (ErrorT e m a) where
+    ErrorT x == ErrorT y = eq1 x y
+
+instance (Ord e, Ord1 m, Ord a) => Ord (ErrorT e m a) where
+    compare (ErrorT x) (ErrorT y) = compare1 x y
+
+instance (Read e, Read1 m, Read a) => Read (ErrorT e m a) where
+    readsPrec = readsData $ readsUnary1 "ErrorT" ErrorT
+
+instance (Show e, Show1 m, Show a) => Show (ErrorT e m a) where
+    showsPrec d (ErrorT m) = showsUnary1 "ErrorT" d m
+
+instance (Eq e, Eq1 m) => Eq1 (ErrorT e m) where eq1 = (==)
+instance (Ord e, Ord1 m) => Ord1 (ErrorT e m) where compare1 = compare
+instance (Read e, Read1 m) => Read1 (ErrorT e m) where readsPrec1 = readsPrec
+instance (Show e, Show1 m) => Show1 (ErrorT e m) where showsPrec1 = showsPrec
+
+-- | Inverse of 'ErrorT'.
+runErrorT :: ErrorT e m a -> m (Either e a)
+runErrorT (ErrorT m) = m
+
 -- | Map the unwrapped computation using the given function.
 --
 -- * @'runErrorT' ('mapErrorT' f m) = f ('runErrorT' m)@
@@ -192,7 +228,7 @@
             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
+    mfix f = ErrorT $ mfix $ \ a -> runErrorT $ f $ case a of
         Right r -> r
         _       -> error "empty mfix argument"
 
@@ -229,22 +265,19 @@
         Right r -> return (Right r)
 
 -- | Lift a @callCC@ operation to the new monad.
-liftCallCC :: (((Either e a -> m (Either e b)) -> m (Either e a)) ->
-    m (Either e a)) -> ((a -> ErrorT e m b) -> ErrorT e m a) -> ErrorT e m a
+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)))
+    callCC $ \ c ->
+    runErrorT (f (\ a -> ErrorT $ c (Right a)))
 
 -- | Lift a @listen@ operation to the new monad.
-liftListen :: Monad m =>
-    (m (Either e a) -> m (Either e a,w)) -> ErrorT e m a -> ErrorT e m (a,w)
+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 => (m (Either e a,w -> w) -> m (Either e a)) ->
-    ErrorT e m (a,w -> w) -> ErrorT e m a
+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
diff --git a/Control/Monad/Trans/Except.hs b/Control/Monad/Trans/Except.hs
new file mode 100644
--- /dev/null
+++ b/Control/Monad/Trans/Except.hs
@@ -0,0 +1,230 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Control.Monad.Trans.Except
+-- Copyright   :  (C) 2013 Ross Paterson
+-- License     :  BSD-style (see the file LICENSE)
+--
+-- Maintainer  :  ross@soi.city.ac.uk
+-- Stability   :  experimental
+-- Portability :  portable
+--
+-- This monad transformer extends a monad with the ability throw exceptions.
+--
+-- A sequence of actions terminates normally, producing a value,
+-- only if none of the actions in the sequence throws an exception.
+-- If one throws an exception, the rest of the sequence is skipped and
+-- the composite action exits with that exception.
+--
+-- If the value of the exception is not required, the variant in
+-- "Control.Monad.Trans.Maybe" may be used instead.
+-----------------------------------------------------------------------------
+
+module Control.Monad.Trans.Except (
+    -- * The Except monad
+    Except,
+    except,
+    runExcept,
+    mapExcept,
+    withExcept,
+    -- * The ExceptT monad transformer
+    ExceptT(..),
+    runExceptT,
+    mapExceptT,
+    withExceptT,
+    -- * Exception operations
+    throwE,
+    catchE,
+    -- * Lifting other operations
+    liftCallCC,
+    liftListen,
+    liftPass,
+  ) where
+
+import Control.Monad.IO.Class
+import Control.Monad.Signatures
+import Control.Monad.Trans.Class
+import Data.Functor.Classes
+import Data.Functor.Identity
+
+import Control.Applicative
+import Control.Monad
+import Control.Monad.Fix
+import Data.Foldable (Foldable(foldMap))
+import Data.Monoid
+import Data.Traversable (Traversable(traverse))
+
+-- | The parameterizable exception monad.
+--
+-- Computations are either exceptions or normal values.
+--
+-- The 'return' function returns a normal value, while @>>=@ exits
+-- on the first exception.
+type Except e = ExceptT e Identity
+
+-- | Constructor for computations in the exception monad.
+-- (The inverse of 'runExcept').
+except :: Either e a -> Except e a
+except m = ExceptT (Identity m)
+
+-- | Extractor for computations in the exception monad.
+-- (The inverse of 'except').
+runExcept :: Except e a -> Either e a
+runExcept (ExceptT m) = runIdentity m
+
+-- | Map the unwrapped computation using the given function.
+--
+-- * @'runExcept' ('mapExcept' f m) = f ('runExcept' m)@
+mapExcept :: (Either e a -> Either e' b)
+        -> Except e a
+        -> Except e' b
+mapExcept f = mapExceptT (Identity . f . runIdentity)
+
+-- | Transform any exceptions thrown by the computation using the given
+-- function (a specialization of 'withExceptT').
+withExcept :: (e -> e') -> Except e a -> Except e' a
+withExcept = withExceptT
+
+-- | A monad transformer that adds exceptions to other monads.
+--
+-- @ExceptT@ constructs a monad parameterized over two things:
+--
+-- * e - The exception type.
+--
+-- * m - The inner 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))
+
+instance (Eq e, Eq1 m, Eq a) => Eq (ExceptT e m a) where
+    ExceptT x == ExceptT y = eq1 x y
+
+instance (Ord e, Ord1 m, Ord a) => Ord (ExceptT e m a) where
+    compare (ExceptT x) (ExceptT y) = compare1 x y
+
+instance (Read e, Read1 m, Read a) => Read (ExceptT e m a) where
+    readsPrec = readsData $ readsUnary1 "ExceptT" ExceptT
+
+instance (Show e, Show1 m, Show a) => Show (ExceptT e m a) where
+    showsPrec d (ExceptT m) = showsUnary1 "ExceptT" d m
+
+instance (Eq e, Eq1 m) => Eq1 (ExceptT e m) where eq1 = (==)
+instance (Ord e, Ord1 m) => Ord1 (ExceptT e m) where compare1 = compare
+instance (Read e, Read1 m) => Read1 (ExceptT e m) where readsPrec1 = readsPrec
+instance (Show e, Show1 m) => Show1 (ExceptT e m) where showsPrec1 = showsPrec
+
+-- | The inverse of 'ExceptT'.
+runExceptT :: ExceptT e m a -> m (Either e a)
+runExceptT (ExceptT m) = m
+
+-- | Map the unwrapped computation using the given function.
+--
+-- * @'runExceptT' ('mapExceptT' f m) = f ('runExceptT' m)@
+mapExceptT :: (m (Either e a) -> n (Either e' b))
+        -> ExceptT e m a
+        -> ExceptT e' n b
+mapExceptT f m = ExceptT $ f (runExceptT m)
+
+-- | Transform any exceptions thrown by the computation using the
+-- given function.
+withExceptT :: (Functor m) => (e -> e') -> ExceptT e m a -> ExceptT e' m a
+withExceptT f = mapExceptT $ fmap $ either (Left . f) Right
+
+instance (Functor m) => Functor (ExceptT e m) where
+    fmap f = ExceptT . fmap (fmap f) . runExceptT
+
+instance (Foldable f) => Foldable (ExceptT e f) where
+    foldMap f (ExceptT a) = foldMap (either (const mempty) f) a
+
+instance (Traversable f) => Traversable (ExceptT e f) where
+    traverse f (ExceptT a) =
+        ExceptT <$> traverse (either (pure . Left) (fmap Right . f)) a
+
+instance (Functor m, Monad m) => Applicative (ExceptT e m) where
+    pure a = ExceptT $ return (Right a)
+    ExceptT f <*> ExceptT v = ExceptT $ do
+        mf <- f
+        case mf of
+            Left e -> return (Left e)
+            Right k -> do
+                mv <- v
+                case mv of
+                    Left e -> return (Left e)
+                    Right x -> return (Right (k x))
+
+instance (Functor m, Monad m, Monoid e) => Alternative (ExceptT e m) where
+    empty = mzero
+    (<|>) = mplus
+
+instance (Monad m) => Monad (ExceptT e m) where
+    return a = ExceptT $ return (Right a)
+    m >>= k = ExceptT $ do
+        a <- runExceptT m
+        case a of
+            Left e -> return (Left e)
+            Right x -> runExceptT (k x)
+    fail = ExceptT . fail
+
+instance (Monad m, Monoid e) => MonadPlus (ExceptT e m) where
+    mzero = ExceptT $ return (Left mempty)
+    ExceptT m `mplus` ExceptT n = ExceptT $ do
+        a <- m
+        case a of
+            Left e -> liftM (either (Left . mappend e) Right) n
+            Right x -> return (Right x)
+
+instance (MonadFix m) => MonadFix (ExceptT e m) where
+    mfix f = ExceptT $ mfix $ \ a -> runExceptT $ f $ case a of
+        Right x -> x
+        Left _ -> error "mfix ExceptT: Left"
+
+instance MonadTrans (ExceptT e) where
+    lift = ExceptT . liftM Right
+
+instance (MonadIO m) => MonadIO (ExceptT e m) where
+    liftIO = lift . liftIO
+
+-- | Signal an exception value @e@.
+--
+-- * @'runExceptT' ('throwE' e) = 'return' ('Left' e)@
+--
+-- * @'throwE' e >>= m = 'throwE' e@
+throwE :: (Monad m) => e -> ExceptT e m a
+throwE = ExceptT . return . Left
+
+-- | Handle an exception.
+--
+-- * @'catchE' h ('lift' m) = 'lift' m@
+--
+-- * @'catchE' h ('throwE' e) = h e@
+catchE :: (Monad m) =>
+    ExceptT e m a               -- ^ the inner computation
+    -> (e -> ExceptT e' m a)    -- ^ a handler for exceptions in the inner
+                                -- computation
+    -> ExceptT e' m a
+m `catchE` h = ExceptT $ do
+    a <- runExceptT m
+    case a of
+        Left  l -> runExceptT (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 (ExceptT e m) a b
+liftCallCC callCC f = ExceptT $
+    callCC $ \ c ->
+    runExceptT (f (\ a -> ExceptT $ c (Right a)))
+
+-- | Lift a @listen@ operation to the new monad.
+liftListen :: (Monad m) => Listen w m (Either e a) -> Listen w (ExceptT e m) a
+liftListen listen = mapExceptT $ \ 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 (ExceptT e m) a
+liftPass pass = mapExceptT $ \ m -> pass $ do
+    a <- m
+    return $! case a of
+        Left l -> (Left l, id)
+        Right (r, f) -> (Right r, f)
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
@@ -16,23 +16,44 @@
 module Control.Monad.Trans.Identity (
     -- * The identity monad transformer
     IdentityT(..),
+    runIdentityT,
     mapIdentityT,
     -- * Lifting other operations
     liftCatch,
     liftCallCC,
   ) where
 
+import Control.Monad.IO.Class (MonadIO(liftIO))
+import Control.Monad.Signatures
+import Control.Monad.Trans.Class (MonadTrans(lift))
+import Data.Functor.Classes
+
 import Control.Applicative
 import Control.Monad (MonadPlus(mzero, mplus))
 import Control.Monad.Fix (MonadFix(mfix))
-import Control.Monad.IO.Class (MonadIO(liftIO))
-import Control.Monad.Trans.Class (MonadTrans(lift))
 import Data.Foldable (Foldable(foldMap))
 import Data.Traversable (Traversable(traverse))
 
 -- | The trivial monad transformer, which maps a monad to an equivalent monad.
-newtype IdentityT m a = IdentityT { runIdentityT :: m a }
+newtype IdentityT f a = IdentityT (f a)
 
+instance (Eq1 f, Eq a) => Eq (IdentityT f a) where
+    IdentityT x == IdentityT y = eq1 x y
+
+instance (Ord1 f, Ord a) => Ord (IdentityT f a) where
+    compare (IdentityT x) (IdentityT y) = compare1 x y
+
+instance (Read1 f, Read a) => Read (IdentityT f a) where
+    readsPrec = readsData $ readsUnary1 "IdentityT" IdentityT
+
+instance (Show1 f, Show a) => Show (IdentityT f a) where
+    showsPrec d (IdentityT m) = showsUnary1 "IdentityT" d m
+
+instance (Eq1 f) => Eq1 (IdentityT f) where eq1 = (==)
+instance (Ord1 f) => Ord1 (IdentityT f) where compare1 = compare
+instance (Read1 f) => Read1 (IdentityT f) where readsPrec1 = readsPrec
+instance (Show1 f) => Show1 (IdentityT f) where showsPrec1 = showsPrec
+
 instance (Functor m) => Functor (IdentityT m) where
     fmap f = mapIdentityT (fmap f)
 
@@ -68,6 +89,10 @@
 instance MonadTrans IdentityT where
     lift = IdentityT
 
+-- | The inverse of 'IdentityT'.
+runIdentityT :: IdentityT f a -> f a
+runIdentityT (IdentityT m) = m
+
 -- | Lift a unary operation to the new monad.
 mapIdentityT :: (m a -> n b) -> IdentityT m a -> IdentityT n b
 mapIdentityT f = IdentityT . f . runIdentityT
@@ -78,12 +103,10 @@
 lift2IdentityT f a b = IdentityT (f (runIdentityT a) (runIdentityT b))
 
 -- | Lift a @callCC@ operation to the new monad.
-liftCallCC :: (((a -> m b) -> m a) ->
-    m a) -> ((a -> IdentityT m b) -> IdentityT m a) -> IdentityT m a
+liftCallCC :: CallCC m a b -> CallCC (IdentityT m) a b
 liftCallCC callCC f =
     IdentityT $ callCC $ \ c -> runIdentityT (f (IdentityT . c))
 
--- | Lift a @catchError@ operation to the new monad.
-liftCatch :: (m a -> (e -> m a) -> m a) ->
-    IdentityT m a -> (e -> IdentityT m a) -> IdentityT m a
+-- | Lift a @catchE@ operation to the new monad.
+liftCatch :: Catch e m a -> Catch e (IdentityT m) a
 liftCatch f m h = IdentityT $ f (runIdentityT m) (runIdentityT . h)
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
@@ -16,6 +16,7 @@
 module Control.Monad.Trans.List (
     -- * The ListT monad transformer
     ListT(..),
+    runListT,
     mapListT,
     -- * Lifting other operations
     liftCallCC,
@@ -23,7 +24,9 @@
   ) 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
@@ -33,8 +36,29 @@
 -- | 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] }
+newtype ListT m a = ListT (m [a])
 
+instance (Eq1 m, Eq a) => Eq (ListT m a) where
+    ListT x == ListT y = eq1 x y
+
+instance (Ord1 m, Ord a) => Ord (ListT m a) where
+    compare (ListT x) (ListT y) = compare1 x y
+
+instance (Read1 m, Read a) => Read (ListT m a) where
+    readsPrec = readsData $ readsUnary1 "ListT" ListT
+
+instance (Show1 m, Show a) => Show (ListT m a) where
+    showsPrec d (ListT m) = showsUnary1 "ListT" d m
+
+instance (Eq1 m) => Eq1 (ListT m) where eq1 = (==)
+instance (Ord1 m) => Ord1 (ListT m) where compare1 = compare
+instance (Read1 m) => Read1 (ListT m) where readsPrec1 = readsPrec
+instance (Show1 m) => Show1 (ListT m) where showsPrec1 = showsPrec
+
+-- | The inverse of 'ListT'.
+runListT :: ListT m a -> m [a]
+runListT (ListT m) = m
+
 -- | Map between 'ListT' computations.
 --
 -- * @'runListT' ('mapListT' f m) = f ('runListT' m)@
@@ -44,10 +68,10 @@
 instance (Functor m) => Functor (ListT m) where
     fmap f = mapListT $ fmap $ map f
 
-instance Foldable f => Foldable (ListT f) where
+instance (Foldable f) => Foldable (ListT f) where
     foldMap f (ListT a) = foldMap (foldMap f) a
 
-instance Traversable f => Traversable (ListT f) where
+instance (Traversable f) => Traversable (ListT f) where
     traverse f (ListT a) = ListT <$> traverse (traverse f) a
 
 instance (Applicative m) => Applicative (ListT m) where
@@ -82,14 +106,12 @@
     liftIO = lift . liftIO
 
 -- | Lift a @callCC@ operation to the new monad.
-liftCallCC :: ((([a] -> m [b]) -> m [a]) -> m [a]) ->
-    ((a -> ListT m b) -> ListT m a) -> ListT m a
+liftCallCC :: CallCC m [a] [b] -> CallCC (ListT m) a b
 liftCallCC callCC f = ListT $
-    callCC $ \c ->
-    runListT (f (\a -> ListT $ c [a]))
+    callCC $ \ c ->
+    runListT (f (\ a -> ListT $ c [a]))
 
--- | Lift a @catchError@ operation to the new monad.
-liftCatch :: (m [a] -> (e -> m [a]) -> m [a]) ->
-    ListT m a -> (e -> ListT m a) -> ListT m a
-liftCatch catchError m h = ListT $ runListT m
-    `catchError` \e -> runListT (h e)
+-- | 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)
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
@@ -8,20 +8,25 @@
 -- Stability   :  experimental
 -- Portability :  portable
 --
--- The 'MaybeT' monad transformer adds the ability to fail to a monad.
+-- The 'MaybeT' monad transformer extends a monad with the ability to exit
+-- the computation without returning a value.
 --
--- A sequence of actions succeeds, producing a value, only if all the
--- actions in the sequence are successful.  If one fails, the rest of
--- the sequence is skipped and the composite action fails.
+-- A sequence of actions produces a value only if all the actions in
+-- the sequence do.  If one exits, the rest of the sequence is skipped
+-- and the composite action exits.
 --
--- For a variant allowing a range of error values, see
--- "Control.Monad.Trans.Error".
+-- For a variant allowing a range of exception values, see
+-- "Control.Monad.Trans.Except".
 -----------------------------------------------------------------------------
 
 module Control.Monad.Trans.Maybe (
     -- * The MaybeT monad transformer
     MaybeT(..),
+    runMaybeT,
     mapMaybeT,
+    -- * Conversion
+    maybeToExceptT,
+    exceptToMaybeT,
     -- * Lifting other operations
     liftCallCC,
     liftCatch,
@@ -30,7 +35,10 @@
   ) where
 
 import Control.Monad.IO.Class
+import Control.Monad.Signatures
 import Control.Monad.Trans.Class
+import Control.Monad.Trans.Except (ExceptT(..))
+import Data.Functor.Classes
 
 import Control.Applicative
 import Control.Monad (MonadPlus(mzero, mplus), liftM, ap)
@@ -42,18 +50,50 @@
 -- | The parameterizable maybe monad, obtained by composing an arbitrary
 -- monad with the 'Maybe' monad.
 --
--- Computations are actions that may produce a value or fail.
+-- Computations are actions that may produce a value or exit.
 --
--- The 'return' function yields a successful computation, while @>>=@
--- sequences two subcomputations, failing on the first error.
-newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) }
+-- The 'return' function yields a computation that produces that
+-- value, while @>>=@ sequences two subcomputations, exiting if either
+-- computation does.
+newtype MaybeT m a = MaybeT (m (Maybe a))
 
+instance (Eq1 m, Eq a) => Eq (MaybeT m a) where
+    MaybeT x == MaybeT y = eq1 x y
+
+instance (Ord1 m, Ord a) => Ord (MaybeT m a) where
+    compare (MaybeT x) (MaybeT y) = compare1 x y
+
+instance (Read1 m, Read a) => Read (MaybeT m a) where
+    readsPrec = readsData $ readsUnary1 "MaybeT" MaybeT
+
+instance (Show1 m, Show a) => Show (MaybeT m a) where
+    showsPrec d (MaybeT m) = showsUnary1 "MaybeT" d m
+
+instance (Eq1 m) => Eq1 (MaybeT m) where eq1 = (==)
+instance (Ord1 m) => Ord1 (MaybeT m) where compare1 = compare
+instance (Read1 m) => Read1 (MaybeT m) where readsPrec1 = readsPrec
+instance (Show1 m) => Show1 (MaybeT m) where showsPrec1 = showsPrec
+
+-- | The inverse of 'MaybeT'.
+runMaybeT :: MaybeT m a -> m (Maybe a)
+runMaybeT (MaybeT m) = m
+
 -- | Transform the computation inside a @MaybeT@.
 --
 -- * @'runMaybeT' ('mapMaybeT' f m) = f ('runMaybeT' m)@
 mapMaybeT :: (m (Maybe a) -> n (Maybe b)) -> MaybeT m a -> MaybeT n b
 mapMaybeT f = MaybeT . f . runMaybeT
 
+-- | Convert a 'MaybeT' computation to 'ExceptT', with a default
+-- exception value.
+maybeToExceptT :: (Functor m) => e -> MaybeT m a -> ExceptT e m a
+maybeToExceptT e (MaybeT m) = ExceptT $ fmap (maybe (Left e) Right) m
+
+-- | Convert a 'ExceptT' computation to 'MaybeT', discarding the
+-- value of any exception.
+exceptToMaybeT :: (Functor m) => ExceptT e m a -> MaybeT m a
+exceptToMaybeT (ExceptT m) = MaybeT $ fmap (either (const Nothing) Just) m
+
 instance (Functor m) => Functor (MaybeT m) where
     fmap f = mapMaybeT (fmap (fmap f))
 
@@ -99,26 +139,22 @@
     liftIO = lift . liftIO
 
 -- | Lift a @callCC@ operation to the new monad.
-liftCallCC :: (((Maybe a -> m (Maybe b)) -> m (Maybe a)) ->
-    m (Maybe a)) -> ((a -> MaybeT m b) -> MaybeT m a) -> MaybeT m a
+liftCallCC :: CallCC m (Maybe a) (Maybe b) -> CallCC (MaybeT m) a b
 liftCallCC callCC f =
     MaybeT $ callCC $ \ c -> runMaybeT (f (MaybeT . c . Just))
 
--- | Lift a @catchError@ operation to the new monad.
-liftCatch :: (m (Maybe a) -> (e -> m (Maybe a)) -> m (Maybe a)) ->
-    MaybeT m a -> (e -> MaybeT m a) -> MaybeT m a
+-- | Lift a @catchE@ operation to the new monad.
+liftCatch :: Catch e m (Maybe a) -> Catch e (MaybeT m) a
 liftCatch f m h = MaybeT $ f (runMaybeT m) (runMaybeT . h)
 
 -- | Lift a @listen@ operation to the new monad.
-liftListen :: Monad m =>
-    (m (Maybe a) -> m (Maybe a,w)) -> MaybeT m a -> MaybeT m (a,w)
+liftListen :: (Monad m) => Listen w m (Maybe a) -> Listen w (MaybeT m) a
 liftListen listen = mapMaybeT $ \ m -> do
     (a, w) <- listen m
     return $! fmap (\ r -> (r, w)) a
 
 -- | Lift a @pass@ operation to the new monad.
-liftPass :: Monad m => (m (Maybe a,w -> w) -> m (Maybe a)) ->
-    MaybeT m (a,w -> w) -> MaybeT m a
+liftPass :: (Monad m) => Pass w m (Maybe a) -> Pass w (MaybeT m) a
 liftPass pass = mapMaybeT $ \ m -> pass $ do
     a <- m
     return $! case a of
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
@@ -10,8 +10,8 @@
 -- 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.
+-- This version is lazy; for a strict version with the same interface,
+-- see "Control.Monad.Trans.RWS.Strict".
 -----------------------------------------------------------------------------
 
 module Control.Monad.Trans.RWS.Lazy (
@@ -25,6 +25,7 @@
     withRWS,
     -- * The RWST monad transformer
     RWST(..),
+    runRWST,
     evalRWST,
     execRWST,
     mapRWST,
@@ -54,6 +55,7 @@
   ) where
 
 import Control.Monad.IO.Class
+import Control.Monad.Signatures
 import Control.Monad.Trans.Class
 import Data.Functor.Identity
 
@@ -114,8 +116,12 @@
 -- | 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 { runRWST :: r -> s -> m (a, s, w) }
+newtype RWST r w s m a = RWST (r -> s -> m (a, s, w))
 
+-- | The inverse of 'RWST'.
+runRWST :: RWST r w s m a -> r -> s -> m (a, s, w)
+runRWST (RWST m) = m
+
 -- | Evaluate a computation with the given initial state and environment,
 -- returning the final value and output, discarding the final state.
 evalRWST :: (Monad m)
@@ -142,17 +148,17 @@
 --
 -- * @'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 f m = RWST $ \r s -> f (runRWST m r s)
+mapRWST f m = RWST $ \ r s -> f (runRWST m r s)
 
 -- | @'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 (runRWST m) (f r s)
+withRWST f m = RWST $ \ r s -> uncurry (runRWST m) (f r s)
 
 instance (Functor m) => Functor (RWST r w s m) where
-    fmap f m = RWST $ \r s ->
+    fmap f m = RWST $ \ r s ->
         fmap (\ ~(a, s', w) -> (f a, s', w)) $ runRWST m r s
 
 instance (Monoid w, Functor m, Monad m) => Applicative (RWST r w s m) where
@@ -164,22 +170,22 @@
     (<|>) = mplus
 
 instance (Monoid w, Monad m) => Monad (RWST r w s m) where
-    return a = RWST $ \_ s -> return (a, s, mempty)
-    m >>= k  = RWST $ \r s -> do
+    return a = RWST $ \ _ s -> return (a, s, mempty)
+    m >>= k  = RWST $ \ r s -> do
         ~(a, s', w)  <- runRWST m r s
         ~(b, s'',w') <- runRWST (k a) r s'
         return (b, s'', w `mappend` w')
-    fail msg = RWST $ \_ _ -> fail msg
+    fail msg = RWST $ \ _ _ -> fail msg
 
 instance (Monoid w, MonadPlus m) => MonadPlus (RWST r w s m) where
-    mzero       = RWST $ \_ _ -> mzero
-    m `mplus` n = RWST $ \r s -> runRWST m r s `mplus` runRWST n r s
+    mzero       = RWST $ \ _ _ -> mzero
+    m `mplus` n = RWST $ \ r s -> runRWST m r s `mplus` runRWST n r s
 
 instance (Monoid w, MonadFix m) => MonadFix (RWST r w s m) where
-    mfix f = RWST $ \r s -> mfix $ \ ~(a, _, _) -> runRWST (f a) r s
+    mfix f = RWST $ \ r s -> mfix $ \ ~(a, _, _) -> runRWST (f a) r s
 
 instance (Monoid w) => MonadTrans (RWST r w s) where
-    lift m = RWST $ \_ s -> do
+    lift m = RWST $ \ _ s -> do
         a <- m
         return (a, s, mempty)
 
@@ -195,37 +201,37 @@
 
 -- | Fetch the value of the environment.
 ask :: (Monoid w, Monad m) => RWST r w s m r
-ask = RWST $ \r s -> return (r, s, mempty)
+ask = RWST $ \ r s -> return (r, s, mempty)
 
 -- | Execute a computation in a modified environment
 --
 -- * @'runRWST' ('local' f m) r s = 'runRWST' m (f r) s@
 local :: (Monoid w, Monad m) => (r -> r) -> RWST r w s m a -> RWST r w s m a
-local f m = RWST $ \r s -> runRWST m (f r) s
+local f m = RWST $ \ r s -> runRWST m (f r) s
 
 -- | Retrieve a function of the current environment.
 --
 -- * @'asks' f = 'liftM' f 'ask'@
 asks :: (Monoid w, Monad m) => (r -> a) -> RWST r w s m a
-asks f = RWST $ \r s -> return (f r, s, mempty)
+asks f = RWST $ \ r s -> return (f r, s, mempty)
 
 -- ---------------------------------------------------------------------------
 -- Writer operations
 
 -- | Construct a writer computation from a (result, output) pair.
-writer :: Monad m => (a, w) -> RWST r w s m a
-writer (a, w) = RWST $ \_ s -> return (a, s, w)
+writer :: (Monad m) => (a, w) -> RWST r w s m a
+writer (a, w) = RWST $ \ _ s -> return (a, s, w)
 
 -- | @'tell' w@ is an action that produces the output @w@.
 tell :: (Monoid w, Monad m) => w -> RWST r w s m ()
-tell w = RWST $ \_ s -> return ((),s,w)
+tell w = RWST $ \ _ s -> return ((),s,w)
 
 -- | @'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)@
+-- * @'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 m = RWST $ \r s -> do
+listen m = RWST $ \ r s -> do
     ~(a, s', w) <- runRWST m r s
     return ((a, w), s', w)
 
@@ -234,9 +240,9 @@
 --
 -- * @'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)@
+-- * @'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 -> do
+listens f m = RWST $ \ r s -> do
     ~(a, s', w) <- runRWST m r s
     return ((a, f w), s', w)
 
@@ -244,9 +250,9 @@
 -- 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)@
+-- * @'runRWST' ('pass' m) r s = 'liftM' (\\ ((a, f), w) -> (a, f w)) ('runRWST' m r s)@
 pass :: (Monoid w, Monad m) => RWST r w s m (a, w -> w) -> RWST r w s m a
-pass m = RWST $ \r s -> do
+pass m = RWST $ \ r s -> do
     ~((a, f), s', w) <- runRWST m r s
     return (a, s', f w)
 
@@ -254,11 +260,11 @@
 -- applies the function @f@ to its output, leaving the return value
 -- unchanged.
 --
--- * @'censor' f m = 'pass' ('liftM' (\\x -> (x,f)) m)@
+-- * @'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)@
+-- * @'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 -> do
+censor f m = RWST $ \ r s -> do
     ~(a, s', w) <- runRWST m r s
     return (a, s', f w)
 
@@ -267,51 +273,48 @@
 
 -- | Construct a state monad computation from a state transformer function.
 state :: (Monoid w, Monad m) => (s -> (a,s)) -> RWST r w s m a
-state f = RWST $ \_ s -> let (a,s') = f s  in  return (a, s', mempty)
+state f = RWST $ \ _ s -> let (a,s') = f s  in  return (a, s', mempty)
 
 -- | Fetch the current value of the state within the monad.
 get :: (Monoid w, Monad m) => RWST r w s m s
-get = RWST $ \_ s -> return (s, s, mempty)
+get = RWST $ \ _ s -> return (s, s, mempty)
 
 -- | @'put' s@ sets the state within the monad to @s@.
 put :: (Monoid w, Monad m) => s -> RWST r w s m ()
-put s = RWST $ \_ _ -> return ((), s, mempty)
+put s = RWST $ \ _ _ -> return ((), s, mempty)
 
 -- | @'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 :: (Monoid w, Monad m) => (s -> s) -> RWST r w s m ()
-modify f = RWST $ \_ s -> return ((), f s, mempty)
+modify f = RWST $ \ _ s -> return ((), f s, mempty)
  
 -- | Get a specific component of the state, using a projection function
 -- supplied.
 --
 -- * @'gets' f = 'liftM' f 'get'@
 gets :: (Monoid w, Monad m) => (s -> a) -> RWST r w s m a
-gets f = RWST $ \_ s -> return (f s, s, mempty)
+gets f = RWST $ \ _ s -> return (f s, s, mempty)
 
 -- | Uniform lifting of a @callCC@ operation to the new monad.
 -- This version rolls back to the original state on entering the
 -- continuation.
 liftCallCC :: (Monoid w) =>
-    ((((a,s,w) -> m (b,s,w)) -> m (a,s,w)) -> m (a,s,w)) ->
-    ((a -> RWST r w s m b) -> RWST r w s m a) -> RWST r w s m a
-liftCallCC callCC f = RWST $ \r s ->
-    callCC $ \c ->
-    runRWST (f (\a -> RWST $ \_ _ -> c (a, s, mempty))) r s
+    CallCC m (a,s,w) (b,s,w) -> CallCC (RWST r w s m) a b
+liftCallCC callCC f = RWST $ \ r s ->
+    callCC $ \ c ->
+    runRWST (f (\ a -> RWST $ \ _ _ -> c (a, s, mempty))) r s
 
 -- | In-situ lifting of a @callCC@ operation to the new monad.
 -- This version uses the current state on entering the continuation.
 liftCallCC' :: (Monoid w) =>
-    ((((a,s,w) -> m (b,s,w)) -> m (a,s,w)) -> m (a,s,w)) ->
-    ((a -> RWST r w s m b) -> RWST r w s m a) -> RWST r w s m a
-liftCallCC' callCC f = RWST $ \r s ->
-    callCC $ \c ->
-    runRWST (f (\a -> RWST $ \_ s' -> c (a, s', mempty))) r s
+    CallCC m (a,s,w) (b,s,w) -> CallCC (RWST r w s m) a b
+liftCallCC' callCC f = RWST $ \ r s ->
+    callCC $ \ c ->
+    runRWST (f (\ a -> RWST $ \ _ s' -> c (a, s', mempty))) r s
 
--- | Lift a @catchError@ operation to the new monad.
-liftCatch :: (m (a,s,w) -> (e -> m (a,s,w)) -> m (a,s,w)) ->
-    RWST l w s m a -> (e -> RWST l w s m a) -> RWST l w s m a
-liftCatch catchError m h =
-    RWST $ \r s -> runRWST m r s `catchError` \e -> runRWST (h e) r s
+-- | Lift a @catchE@ operation to the new monad.
+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
@@ -10,8 +10,8 @@
 -- Portability :  portable
 --
 -- A monad transformer that combines 'ReaderT', 'WriterT' and 'StateT'.
--- This version is strict; for a lazy version, see
--- "Control.Monad.Trans.RWS.Lazy", which has the same interface.
+-- This version is strict; for a lazy version with the same interface,
+-- see "Control.Monad.Trans.RWS.Lazy".
 -----------------------------------------------------------------------------
 
 module Control.Monad.Trans.RWS.Strict (
@@ -25,6 +25,7 @@
     withRWS,
     -- * The RWST monad transformer
     RWST(..),
+    runRWST,
     evalRWST,
     execRWST,
     mapRWST,
@@ -54,6 +55,7 @@
   ) where
 
 import Control.Monad.IO.Class
+import Control.Monad.Signatures
 import Control.Monad.Trans.Class
 import Data.Functor.Identity
 
@@ -114,8 +116,12 @@
 -- | 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 { runRWST :: r -> s -> m (a, s, w) }
+newtype RWST r w s m a = RWST (r -> s -> m (a, s, w))
 
+-- | The inverse of 'RWST'.
+runRWST :: RWST r w s m a -> r -> s -> m (a, s, w)
+runRWST (RWST m) = m
+
 -- | Evaluate a computation with the given initial state and environment,
 -- returning the final value and output, discarding the final state.
 evalRWST :: (Monad m)
@@ -142,17 +148,17 @@
 --
 -- * @'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 f m = RWST $ \r s -> f (runRWST m r s)
+mapRWST f m = RWST $ \ r s -> f (runRWST m r s)
 
 -- | @'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 (runRWST m) (f r s)
+withRWST f m = RWST $ \ r s -> uncurry (runRWST m) (f r s)
 
 instance (Functor m) => Functor (RWST r w s m) where
-    fmap f m = RWST $ \r s ->
+    fmap f m = RWST $ \ r s ->
         fmap (\ (a, s', w) -> (f a, s', w)) $ runRWST m r s
 
 instance (Monoid w, Functor m, Monad m) => Applicative (RWST r w s m) where
@@ -164,22 +170,22 @@
     (<|>) = mplus
 
 instance (Monoid w, Monad m) => Monad (RWST r w s m) where
-    return a = RWST $ \_ s -> return (a, s, mempty)
-    m >>= k  = RWST $ \r s -> do
+    return a = RWST $ \ _ s -> return (a, s, mempty)
+    m >>= k  = RWST $ \ r s -> do
         (a, s', w)  <- runRWST m r s
         (b, s'',w') <- runRWST (k a) r s'
         return (b, s'', w `mappend` w')
-    fail msg = RWST $ \_ _ -> fail msg
+    fail msg = RWST $ \ _ _ -> fail msg
 
 instance (Monoid w, MonadPlus m) => MonadPlus (RWST r w s m) where
-    mzero       = RWST $ \_ _ -> mzero
-    m `mplus` n = RWST $ \r s -> runRWST m r s `mplus` runRWST n r s
+    mzero       = RWST $ \ _ _ -> mzero
+    m `mplus` n = RWST $ \ r s -> runRWST m r s `mplus` runRWST n r s
 
 instance (Monoid w, MonadFix m) => MonadFix (RWST r w s m) where
-    mfix f = RWST $ \r s -> mfix $ \ ~(a, _, _) -> runRWST (f a) r s
+    mfix f = RWST $ \ r s -> mfix $ \ ~(a, _, _) -> runRWST (f a) r s
 
 instance (Monoid w) => MonadTrans (RWST r w s) where
-    lift m = RWST $ \_ s -> do
+    lift m = RWST $ \ _ s -> do
         a <- m
         return (a, s, mempty)
 
@@ -195,37 +201,37 @@
 
 -- | Fetch the value of the environment.
 ask :: (Monoid w, Monad m) => RWST r w s m r
-ask = RWST $ \r s -> return (r, s, mempty)
+ask = RWST $ \ r s -> return (r, s, mempty)
 
 -- | Execute a computation in a modified environment
 --
 -- * @'runRWST' ('local' f m) r s = 'runRWST' m (f r) s@
 local :: (Monoid w, Monad m) => (r -> r) -> RWST r w s m a -> RWST r w s m a
-local f m = RWST $ \r s -> runRWST m (f r) s
+local f m = RWST $ \ r s -> runRWST m (f r) s
 
 -- | Retrieve a function of the current environment.
 --
 -- * @'asks' f = 'liftM' f 'ask'@
 asks :: (Monoid w, Monad m) => (r -> a) -> RWST r w s m a
-asks f = RWST $ \r s -> return (f r, s, mempty)
+asks f = RWST $ \ r s -> return (f r, s, mempty)
 
 -- ---------------------------------------------------------------------------
 -- Writer operations
 
 -- | Construct a writer computation from a (result, output) pair.
-writer :: Monad m => (a, w) -> RWST r w s m a
-writer (a, w) = RWST $ \_ s -> return (a, s, w)
+writer :: (Monad m) => (a, w) -> RWST r w s m a
+writer (a, w) = RWST $ \ _ s -> return (a, s, w)
 
 -- | @'tell' w@ is an action that produces the output @w@.
 tell :: (Monoid w, Monad m) => w -> RWST r w s m ()
-tell w = RWST $ \_ s -> return ((),s,w)
+tell w = RWST $ \ _ s -> return ((),s,w)
 
 -- | @'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)@
+-- * @'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 m = RWST $ \r s -> do
+listen m = RWST $ \ r s -> do
     (a, s', w) <- runRWST m r s
     return ((a, w), s', w)
 
@@ -234,9 +240,9 @@
 --
 -- * @'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)@
+-- * @'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 -> do
+listens f m = RWST $ \ r s -> do
     (a, s', w) <- runRWST m r s
     return ((a, f w), s', w)
 
@@ -244,9 +250,9 @@
 -- 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)@
+-- * @'runRWST' ('pass' m) r s = 'liftM' (\\ ((a, f), w) -> (a, f w)) ('runRWST' m r s)@
 pass :: (Monoid w, Monad m) => RWST r w s m (a, w -> w) -> RWST r w s m a
-pass m = RWST $ \r s -> do
+pass m = RWST $ \ r s -> do
     ((a, f), s', w) <- runRWST m r s
     return (a, s', f w)
 
@@ -254,11 +260,11 @@
 -- applies the function @f@ to its output, leaving the return value
 -- unchanged.
 --
--- * @'censor' f m = 'pass' ('liftM' (\\x -> (x,f)) m)@
+-- * @'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)@
+-- * @'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 -> do
+censor f m = RWST $ \ r s -> do
     (a, s', w) <- runRWST m r s
     return (a, s', f w)
 
@@ -267,51 +273,48 @@
 
 -- | Construct a state monad computation from a state transformer function.
 state :: (Monoid w, Monad m) => (s -> (a,s)) -> RWST r w s m a
-state f = RWST $ \_ s -> case f s of (a,s') -> return (a, s', mempty)
+state f = RWST $ \ _ s -> case f s of (a,s') -> return (a, s', mempty)
 
 -- | Fetch the current value of the state within the monad.
 get :: (Monoid w, Monad m) => RWST r w s m s
-get = RWST $ \_ s -> return (s, s, mempty)
+get = RWST $ \ _ s -> return (s, s, mempty)
 
 -- | @'put' s@ sets the state within the monad to @s@.
 put :: (Monoid w, Monad m) => s -> RWST r w s m ()
-put s = RWST $ \_ _ -> return ((), s, mempty)
+put s = RWST $ \ _ _ -> return ((), s, mempty)
 
 -- | @'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 :: (Monoid w, Monad m) => (s -> s) -> RWST r w s m ()
-modify f = RWST $ \_ s -> return ((), f s, mempty)
+modify f = RWST $ \ _ s -> return ((), f s, mempty)
  
 -- | Get a specific component of the state, using a projection function
 -- supplied.
 --
 -- * @'gets' f = 'liftM' f 'get'@
 gets :: (Monoid w, Monad m) => (s -> a) -> RWST r w s m a
-gets f = RWST $ \_ s -> return (f s, s, mempty)
+gets f = RWST $ \ _ s -> return (f s, s, mempty)
 
 -- | Uniform lifting of a @callCC@ operation to the new monad.
 -- This version rolls back to the original state on entering the
 -- continuation.
 liftCallCC :: (Monoid w) =>
-    ((((a,s,w) -> m (b,s,w)) -> m (a,s,w)) -> m (a,s,w)) ->
-    ((a -> RWST r w s m b) -> RWST r w s m a) -> RWST r w s m a
-liftCallCC callCC f = RWST $ \r s ->
-    callCC $ \c ->
-    runRWST (f (\a -> RWST $ \_ _ -> c (a, s, mempty))) r s
+    CallCC m (a,s,w) (b,s,w) -> CallCC (RWST r w s m) a b
+liftCallCC callCC f = RWST $ \ r s ->
+    callCC $ \ c ->
+    runRWST (f (\ a -> RWST $ \ _ _ -> c (a, s, mempty))) r s
 
 -- | In-situ lifting of a @callCC@ operation to the new monad.
 -- This version uses the current state on entering the continuation.
 liftCallCC' :: (Monoid w) =>
-    ((((a,s,w) -> m (b,s,w)) -> m (a,s,w)) -> m (a,s,w)) ->
-    ((a -> RWST r w s m b) -> RWST r w s m a) -> RWST r w s m a
-liftCallCC' callCC f = RWST $ \r s ->
-    callCC $ \c ->
-    runRWST (f (\a -> RWST $ \_ s' -> c (a, s', mempty))) r s
+    CallCC m (a,s,w) (b,s,w) -> CallCC (RWST r w s m) a b
+liftCallCC' callCC f = RWST $ \ r s ->
+    callCC $ \ c ->
+    runRWST (f (\ a -> RWST $ \ _ s' -> c (a, s', mempty))) r s
 
--- | Lift a @catchError@ operation to the new monad.
-liftCatch :: (m (a,s,w) -> (e -> m (a,s,w)) -> m (a,s,w)) ->
-    RWST l w s m a -> (e -> RWST l w s m a) -> RWST l w s m a
-liftCatch catchError m h =
-    RWST $ \r s -> runRWST m r s `catchError` \e -> runRWST (h e) r s
+-- | Lift a @catchE@ operation to the new monad.
+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,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Control.Monad.Trans.Reader
@@ -25,6 +26,7 @@
     withReader,
     -- * The ReaderT monad transformer
     ReaderT(..),
+    runReaderT,
     mapReaderT,
     withReaderT,
     -- * Reader operations
@@ -37,13 +39,16 @@
     ) where
 
 import Control.Monad.IO.Class
+import Control.Monad.Signatures
 import Control.Monad.Trans.Class
 import Data.Functor.Identity
 
 import Control.Applicative
 import Control.Monad
 import Control.Monad.Fix
-import Control.Monad.Instances ()
+#if !(MIN_VERSION_base(4,6,0))
+import Control.Monad.Instances ()  -- deprecated from base-4.6
+#endif
 
 -- | The parameterizable reader monad.
 --
@@ -54,7 +59,7 @@
 type Reader r = ReaderT r Identity
 
 -- | Constructor for computations in the reader monad (equivalent to 'asks').
-reader :: Monad m => (r -> a) -> ReaderT r m a
+reader :: (Monad m) => (r -> a) -> ReaderT r m a
 reader f = ReaderT (return . f)
 
 -- | Runs a @Reader@ and extracts the final value from it.
@@ -85,11 +90,13 @@
 --
 -- The 'return' function ignores the environment, while @>>=@ passes
 -- the inherited environment to both subcomputations.
-newtype ReaderT r m a = ReaderT {
-        -- | The underlying computation, as a function of the environment.
-        runReaderT :: r -> m a
-    }
+newtype ReaderT r m a = ReaderT (r -> m a)
 
+-- | The underlying computation, as a function of the environment.
+-- (inverse of 'ReaderT')
+runReaderT :: ReaderT r m a -> r -> m a
+runReaderT (ReaderT m) = m
+
 -- | Transform the computation inside a @ReaderT@.
 --
 -- * @'runReaderT' ('mapReaderT' f m) = f . 'runReaderT' m@
@@ -163,18 +170,12 @@
 asks f = ReaderT (return . f)
 
 -- | Lift a @callCC@ operation to the new monad.
-liftCallCC ::
-    (((a -> m b) -> m a) -> m a)        -- ^ @callCC@ on the argument monad.
-    -> ((a -> ReaderT r m b) -> ReaderT r m a) -> ReaderT r m a
+liftCallCC :: CallCC m a b -> CallCC (ReaderT r m) a b
 liftCallCC callCC f = ReaderT $ \ r ->
     callCC $ \ c ->
     runReaderT (f (ReaderT . const . c)) r
 
--- | Lift a @catchError@ operation to the new monad.
-liftCatch ::
-    (m a -> (e -> m a) -> m a)          -- ^ @catch@ on the argument monad.
-    -> ReaderT r m a                    -- ^ Computation to attempt.
-    -> (e -> ReaderT r m a)             -- ^ Exception handler.
-    -> ReaderT r m a
+-- | Lift a @catchE@ operation to the new monad.
+liftCatch :: Catch e m a -> Catch e (ReaderT r m) a
 liftCatch f m h =
     ReaderT $ \ r -> f (runReaderT m r) (\ e -> runReaderT (h e) r)
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
@@ -12,16 +12,20 @@
 -- Lazy state monads, passing an updatable state through a computation.
 -- See below for examples.
 --
--- In this version, sequencing of computations is lazy.
--- For a strict version, see "Control.Monad.Trans.State.Strict", which
--- has the same interface.
---
 -- Some computations may not require the full power of state transformers:
 --
 -- * For a read-only state, see "Control.Monad.Trans.Reader".
 --
 -- * To accumulate a value without using it on the way, see
 --   "Control.Monad.Trans.Writer".
+--
+-- In this version, sequencing of computations is lazy, so that for
+-- example the following produces a usable result:
+--
+-- > evalState (sequence $ repeat $ do { n <- get; put (n*2); return n }) 1
+--
+-- For a strict version with the same interface, see
+-- "Control.Monad.Trans.State.Strict".
 -----------------------------------------------------------------------------
 
 module Control.Monad.Trans.State.Lazy (
@@ -35,6 +39,7 @@
     withState,
     -- * The StateT monad transformer
     StateT(..),
+    runStateT,
     evalStateT,
     execStateT,
     mapStateT,
@@ -43,6 +48,7 @@
     get,
     put,
     modify,
+    modify',
     gets,
     -- * Lifting other operations
     liftCallCC,
@@ -62,6 +68,7 @@
   ) where
 
 import Control.Monad.IO.Class
+import Control.Monad.Signatures
 import Control.Monad.Trans.Class
 import Data.Functor.Identity
 
@@ -79,7 +86,7 @@
 
 -- | Construct a state monad computation from a function.
 -- (The inverse of 'runState'.)
-state :: Monad m
+state :: (Monad m)
       => (s -> (a, s))  -- ^pure state transformer
       -> StateT s m a   -- ^equivalent state-passing computation
 state f = StateT (return . f)
@@ -133,9 +140,14 @@
 -- The 'return' function leaves the state unchanged, while @>>=@ uses
 -- 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) }
+newtype StateT s m a = StateT (s -> m (a,s))
 
 -- | Evaluate a state computation with the given initial state
+-- and return the final value and state. (inverse of 'StateT')
+runStateT :: StateT s m a -> s -> m (a,s)
+runStateT (StateT m) = m
+
+-- | Evaluate a state computation with the given initial state
 -- and return the final value, discarding the final state.
 --
 -- * @'evalStateT' m s = 'liftM' 'fst' ('runStateT' m s)@
@@ -180,21 +192,21 @@
     (<|>) = mplus
 
 instance (Monad m) => Monad (StateT s m) where
-    return a = state $ \s -> (a, s)
-    m >>= k  = StateT $ \s -> do
+    return a = state $ \ s -> (a, s)
+    m >>= k  = StateT $ \ s -> do
         ~(a, s') <- runStateT m s
         runStateT (k a) s'
-    fail str = StateT $ \_ -> fail str
+    fail str = StateT $ \ _ -> fail str
 
 instance (MonadPlus m) => MonadPlus (StateT s m) where
-    mzero       = StateT $ \_ -> mzero
-    m `mplus` n = StateT $ \s -> runStateT m s `mplus` runStateT n s
+    mzero       = StateT $ \ _ -> mzero
+    m `mplus` n = StateT $ \ s -> runStateT m s `mplus` runStateT n s
 
 instance (MonadFix m) => MonadFix (StateT s m) where
-    mfix f = StateT $ \s -> mfix $ \ ~(a, _) -> runStateT (f a) s
+    mfix f = StateT $ \ s -> mfix $ \ ~(a, _) -> runStateT (f a) s
 
 instance MonadTrans (StateT s) where
-    lift m = StateT $ \s -> do
+    lift m = StateT $ \ s -> do
         a <- m
         return (a, s)
 
@@ -203,61 +215,65 @@
 
 -- | Fetch the current value of the state within the monad.
 get :: (Monad m) => StateT s m s
-get = state $ \s -> (s, s)
+get = state $ \ s -> (s, s)
 
 -- | @'put' s@ sets the state within the monad to @s@.
 put :: (Monad m) => s -> StateT s m ()
-put s = state $ \_ -> ((), s)
+put s = state $ \ _ -> ((), s)
 
 -- | @'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) -> StateT s m ()
-modify f = state $ \s -> ((), f s)
+modify f = state $ \ s -> ((), f s)
 
+-- | A variant of 'modify' in which the computation is strict in the
+-- new state.
+--
+-- * @'modify'' f = 'get' >>= (('$!') 'put' . f)@
+modify' :: (Monad m) => (s -> s) -> StateT s m ()
+modify' f = do
+    s <- get
+    put $! f s
+
 -- | Get a specific component of the state, using a projection function
 -- supplied.
 --
 -- * @'gets' f = 'liftM' f 'get'@
 gets :: (Monad m) => (s -> a) -> StateT s m a
-gets f = state $ \s -> (f s, s)
+gets f = state $ \ s -> (f s, s)
 
 -- | Uniform lifting of a @callCC@ operation to the new monad.
 -- This version rolls back to the original state on entering the
 -- continuation.
-liftCallCC :: ((((a,s) -> m (b,s)) -> m (a,s)) -> m (a,s)) ->
-    ((a -> StateT s m b) -> StateT s m a) -> StateT s m a
-liftCallCC callCC f = StateT $ \s ->
-    callCC $ \c ->
-    runStateT (f (\a -> StateT $ \ _ -> c (a, s))) s
+liftCallCC :: CallCC m (a,s) (b,s) -> CallCC (StateT s m) a b
+liftCallCC callCC f = StateT $ \ s ->
+    callCC $ \ c ->
+    runStateT (f (\ a -> StateT $ \ _ -> c (a, s))) s
 
 -- | In-situ lifting of a @callCC@ operation to the new monad.
 -- This version uses the current state on entering the continuation.
 -- It does not satisfy the laws of a monad transformer.
-liftCallCC' :: ((((a,s) -> m (b,s)) -> m (a,s)) -> m (a,s)) ->
-    ((a -> StateT s m b) -> StateT s m a) -> StateT s m a
-liftCallCC' callCC f = StateT $ \s ->
-    callCC $ \c ->
-    runStateT (f (\a -> StateT $ \s' -> c (a, s'))) s
+liftCallCC' :: CallCC m (a,s) (b,s) -> CallCC (StateT s m) a b
+liftCallCC' callCC f = StateT $ \ s ->
+    callCC $ \ c ->
+    runStateT (f (\ a -> StateT $ \ s' -> c (a, s'))) s
 
--- | Lift a @catchError@ operation to the new monad.
-liftCatch :: (m (a,s) -> (e -> m (a,s)) -> m (a,s)) ->
-    StateT s m a -> (e -> StateT s m a) -> StateT s m a
-liftCatch catchError m h =
-    StateT $ \s -> runStateT m s `catchError` \e -> runStateT (h e) s
+-- | Lift a @catchE@ operation to the new monad.
+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
 
 -- | Lift a @listen@ operation to the new monad.
-liftListen :: Monad m =>
-    (m (a,s) -> m ((a,s),w)) -> StateT s m a -> StateT s m (a,w)
-liftListen listen m = StateT $ \s -> do
+liftListen :: (Monad m) => Listen w m (a,s) -> Listen w (StateT s m) a
+liftListen listen m = StateT $ \ s -> do
     ~((a, s'), w) <- listen (runStateT m s)
     return ((a, w), s')
 
 -- | Lift a @pass@ operation to the new monad.
-liftPass :: Monad m =>
-    (m ((a,s),b) -> m (a,s)) -> StateT s m (a,b) -> StateT s m a
-liftPass pass m = StateT $ \s -> pass $ do
+liftPass :: (Monad m) => Pass w m (a,s) -> Pass w (StateT s m) a
+liftPass pass m = StateT $ \ s -> pass $ do
     ~((a, f), s') <- runStateT m s
     return ((a, s'), f)
 
@@ -324,30 +340,20 @@
 
 > numberTree :: Eq a => Tree a -> State (Table a) (Tree Int)
 > numberTree Nil = return Nil
-> numberTree (Node x t1 t2)
->        =  do num <- numberNode x
->              nt1 <- numberTree t1
->              nt2 <- numberTree t2
->              return (Node num nt1 nt2)
->     where
+> numberTree (Node x t1 t2) = do
+>     num <- numberNode x
+>     nt1 <- numberTree t1
+>     nt2 <- numberTree t2
+>     return (Node num nt1 nt2)
+>   where
 >     numberNode :: Eq a => a -> State (Table a) Int
->     numberNode x
->        = do table <- get
->             (newTable, newPos) <- return (nNode x table)
->             put newTable
->             return newPos
->     nNode::  (Eq a) => a -> Table a -> (Table a, Int)
->     nNode x table
->        = case (findIndexInList (== x) table) of
->          Nothing -> (table ++ [x], length table)
->          Just i  -> (table, i)
->     findIndexInList :: (a -> Bool) -> [a] -> Maybe Int
->     findIndexInList = findIndexInListHelp 0
->     findIndexInListHelp _ _ [] = Nothing
->     findIndexInListHelp count f (h:t)
->        = if (f h)
->          then Just count
->          else findIndexInListHelp (count+1) f t
+>     numberNode x = do
+>         table <- get
+>         case elemIndex x table of
+>             Nothing -> do
+>                 put (table ++ [x])
+>                 return (length table)
+>             Just i -> return i
 
 numTree applies numberTree with an initial state:
 
@@ -356,11 +362,5 @@
 
 > testTree = Node "Zero" (Node "One" (Node "Two" Nil Nil) (Node "One" (Node "Zero" Nil Nil) Nil)) Nil
 > numTree testTree => Node 0 (Node 1 (Node 2 Nil Nil) (Node 1 (Node 0 Nil Nil) Nil)) Nil
-
-sumTree is a little helper function that does not use the State monad:
-
-> sumTree :: (Num a) => Tree a -> a
-> sumTree Nil = 0
-> sumTree (Node e t1 t2) = e + (sumTree t1) + (sumTree t2)
 
 -}
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
@@ -12,16 +12,17 @@
 -- Strict state monads, passing an updatable state through a computation.
 -- See below for examples.
 --
--- In this version, sequencing of computations is strict.
--- For a lazy version, see "Control.Monad.Trans.State.Lazy", which
--- has the same interface.
---
 -- Some computations may not require the full power of state transformers:
 --
 -- * For a read-only state, see "Control.Monad.Trans.Reader".
 --
 -- * To accumulate a value without using it on the way, see
 --   "Control.Monad.Trans.Writer".
+--
+-- In this version, sequencing of computations is strict (but computations
+-- are not strict in the state unless you force it with 'seq' or the like).
+-- For a lazy version with the same interface, see
+-- "Control.Monad.Trans.State.Lazy".
 -----------------------------------------------------------------------------
 
 module Control.Monad.Trans.State.Strict (
@@ -35,6 +36,7 @@
     withState,
     -- * The StateT monad transformer
     StateT(..),
+    runStateT,
     evalStateT,
     execStateT,
     mapStateT,
@@ -43,6 +45,7 @@
     get,
     put,
     modify,
+    modify',
     gets,
     -- * Lifting other operations
     liftCallCC,
@@ -62,6 +65,7 @@
   ) where
 
 import Control.Monad.IO.Class
+import Control.Monad.Signatures
 import Control.Monad.Trans.Class
 import Data.Functor.Identity
 
@@ -79,7 +83,7 @@
 
 -- | Construct a state monad computation from a function.
 -- (The inverse of 'runState'.)
-state :: Monad m
+state :: (Monad m)
       => (s -> (a, s))  -- ^pure state transformer
       -> StateT s m a   -- ^equivalent state-passing computation
 state f = StateT (return . f)
@@ -133,9 +137,14 @@
 -- The 'return' function leaves the state unchanged, while @>>=@ uses
 -- 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) }
+newtype StateT s m a = StateT (s -> m (a,s))
 
 -- | Evaluate a state computation with the given initial state
+-- and return the final value and state. (inverse of 'StateT')
+runStateT :: StateT s m a -> s -> m (a,s)
+runStateT (StateT m) = m
+
+-- | Evaluate a state computation with the given initial state
 -- and return the final value, discarding the final state.
 --
 -- * @'evalStateT' m s = 'liftM' 'fst' ('runStateT' m s)@
@@ -180,21 +189,21 @@
     (<|>) = mplus
 
 instance (Monad m) => Monad (StateT s m) where
-    return a = state $ \s -> (a, s)
-    m >>= k  = StateT $ \s -> do
+    return a = state $ \ s -> (a, s)
+    m >>= k  = StateT $ \ s -> do
         (a, s') <- runStateT m s
         runStateT (k a) s'
-    fail str = StateT $ \_ -> fail str
+    fail str = StateT $ \ _ -> fail str
 
 instance (MonadPlus m) => MonadPlus (StateT s m) where
-    mzero       = StateT $ \_ -> mzero
-    m `mplus` n = StateT $ \s -> runStateT m s `mplus` runStateT n s
+    mzero       = StateT $ \ _ -> mzero
+    m `mplus` n = StateT $ \ s -> runStateT m s `mplus` runStateT n s
 
 instance (MonadFix m) => MonadFix (StateT s m) where
-    mfix f = StateT $ \s -> mfix $ \ ~(a, _) -> runStateT (f a) s
+    mfix f = StateT $ \ s -> mfix $ \ ~(a, _) -> runStateT (f a) s
 
 instance MonadTrans (StateT s) where
-    lift m = StateT $ \s -> do
+    lift m = StateT $ \ s -> do
         a <- m
         return (a, s)
 
@@ -203,61 +212,65 @@
 
 -- | Fetch the current value of the state within the monad.
 get :: (Monad m) => StateT s m s
-get = state $ \s -> (s, s)
+get = state $ \ s -> (s, s)
 
 -- | @'put' s@ sets the state within the monad to @s@.
 put :: (Monad m) => s -> StateT s m ()
-put s = state $ \_ -> ((), s)
+put s = state $ \ _ -> ((), s)
 
 -- | @'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) -> StateT s m ()
-modify f = state $ \s -> ((), f s)
+modify f = state $ \ s -> ((), f s)
 
+-- | A variant of 'modify' in which the computation is strict in the
+-- new state.
+--
+-- * @'modify'' f = 'get' >>= (('$!') 'put' . f)@
+modify' :: (Monad m) => (s -> s) -> StateT s m ()
+modify' f = do
+    s <- get
+    put $! f s
+
 -- | Get a specific component of the state, using a projection function
 -- supplied.
 --
 -- * @'gets' f = 'liftM' f 'get'@
 gets :: (Monad m) => (s -> a) -> StateT s m a
-gets f = state $ \s -> (f s, s)
+gets f = state $ \ s -> (f s, s)
 
 -- | Uniform lifting of a @callCC@ operation to the new monad.
 -- This version rolls back to the original state on entering the
 -- continuation.
-liftCallCC :: ((((a,s) -> m (b,s)) -> m (a,s)) -> m (a,s)) ->
-    ((a -> StateT s m b) -> StateT s m a) -> StateT s m a
-liftCallCC callCC f = StateT $ \s ->
-    callCC $ \c ->
-    runStateT (f (\a -> StateT $ \ _ -> c (a, s))) s
+liftCallCC :: CallCC m (a,s) (b,s) -> CallCC (StateT s m) a b
+liftCallCC callCC f = StateT $ \ s ->
+    callCC $ \ c ->
+    runStateT (f (\ a -> StateT $ \ _ -> c (a, s))) s
 
 -- | In-situ lifting of a @callCC@ operation to the new monad.
 -- This version uses the current state on entering the continuation.
 -- It does not satisfy the laws of a monad transformer.
-liftCallCC' :: ((((a,s) -> m (b,s)) -> m (a,s)) -> m (a,s)) ->
-    ((a -> StateT s m b) -> StateT s m a) -> StateT s m a
-liftCallCC' callCC f = StateT $ \s ->
-    callCC $ \c ->
-    runStateT (f (\a -> StateT $ \s' -> c (a, s'))) s
+liftCallCC' :: CallCC m (a,s) (b,s) -> CallCC (StateT s m) a b
+liftCallCC' callCC f = StateT $ \ s ->
+    callCC $ \ c ->
+    runStateT (f (\ a -> StateT $ \ s' -> c (a, s'))) s
 
--- | Lift a @catchError@ operation to the new monad.
-liftCatch :: (m (a,s) -> (e -> m (a,s)) -> m (a,s)) ->
-    StateT s m a -> (e -> StateT s m a) -> StateT s m a
-liftCatch catchError m h =
-    StateT $ \s -> runStateT m s `catchError` \e -> runStateT (h e) s
+-- | Lift a @catchE@ operation to the new monad.
+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
 
 -- | Lift a @listen@ operation to the new monad.
-liftListen :: Monad m =>
-    (m (a,s) -> m ((a,s),w)) -> StateT s m a -> StateT s m (a,w)
-liftListen listen m = StateT $ \s -> do
+liftListen :: (Monad m) => Listen w m (a,s) -> Listen w (StateT s m) a
+liftListen listen m = StateT $ \ s -> do
     ((a, s'), w) <- listen (runStateT m s)
     return ((a, w), s')
 
 -- | Lift a @pass@ operation to the new monad.
-liftPass :: Monad m =>
-    (m ((a,s),b) -> m (a,s)) -> StateT s m (a,b) -> StateT s m a
-liftPass pass m = StateT $ \s -> pass $ do
+liftPass :: (Monad m) => Pass w m (a,s) -> Pass w (StateT s m) a
+liftPass pass m = StateT $ \ s -> pass $ do
     ((a, f), s') <- runStateT m s
     return ((a, s'), f)
 
@@ -324,30 +337,20 @@
 
 > numberTree :: Eq a => Tree a -> State (Table a) (Tree Int)
 > numberTree Nil = return Nil
-> numberTree (Node x t1 t2)
->        =  do num <- numberNode x
->              nt1 <- numberTree t1
->              nt2 <- numberTree t2
->              return (Node num nt1 nt2)
->     where
+> numberTree (Node x t1 t2) = do
+>     num <- numberNode x
+>     nt1 <- numberTree t1
+>     nt2 <- numberTree t2
+>     return (Node num nt1 nt2)
+>   where
 >     numberNode :: Eq a => a -> State (Table a) Int
->     numberNode x
->        = do table <- get
->             (newTable, newPos) <- return (nNode x table)
->             put newTable
->             return newPos
->     nNode::  (Eq a) => a -> Table a -> (Table a, Int)
->     nNode x table
->        = case (findIndexInList (== x) table) of
->          Nothing -> (table ++ [x], length table)
->          Just i  -> (table, i)
->     findIndexInList :: (a -> Bool) -> [a] -> Maybe Int
->     findIndexInList = findIndexInListHelp 0
->     findIndexInListHelp _ _ [] = Nothing
->     findIndexInListHelp count f (h:t)
->        = if (f h)
->          then Just count
->          else findIndexInListHelp (count+1) f t
+>     numberNode x = do
+>         table <- get
+>         case elemIndex x table of
+>             Nothing -> do
+>                 put (table ++ [x])
+>                 return (length table)
+>             Just i -> return i
 
 numTree applies numberTree with an initial state:
 
@@ -356,11 +359,5 @@
 
 > testTree = Node "Zero" (Node "One" (Node "Two" Nil Nil) (Node "One" (Node "Zero" Nil Nil) Nil)) Nil
 > numTree testTree => Node 0 (Node 1 (Node 2 Nil Nil) (Node 1 (Node 0 Nil Nil) Nil)) Nil
-
-sumTree is a little helper function that does not use the State monad:
-
-> sumTree :: (Num a) => Tree a -> a
-> sumTree Nil = 0
-> sumTree (Node e t1 t2) = e + (sumTree t1) + (sumTree t2)
 
 -}
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
@@ -12,12 +12,12 @@
 -- The lazy 'WriterT' monad transformer, which adds collection of
 -- outputs (such as a count or string output) to a given monad.
 --
--- This version builds its output lazily; for a strict version, see
--- "Control.Monad.Trans.Writer.Strict", which has the same interface.
---
 -- 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 lazily; for a strict version with
+-- the same interface, see "Control.Monad.Trans.Writer.Strict".
 -----------------------------------------------------------------------------
 
 module Control.Monad.Trans.Writer.Lazy (
@@ -29,6 +29,7 @@
     mapWriter,
     -- * The WriterT monad transformer
     WriterT(..),
+    runWriterT,
     execWriterT,
     mapWriterT,
     -- * Writer operations
@@ -44,11 +45,13 @@
 
 import Control.Monad.IO.Class
 import Control.Monad.Trans.Class
+import Data.Functor.Classes
 import Data.Functor.Identity
 
 import Control.Applicative
 import Control.Monad
 import Control.Monad.Fix
+import Control.Monad.Signatures
 import Data.Foldable (Foldable(foldMap))
 import Data.Monoid
 import Data.Traversable (Traversable(traverse))
@@ -62,7 +65,7 @@
 
 -- | Construct a writer computation from a (result, output) pair.
 -- (The inverse of 'runWriter'.)
-writer :: Monad m => (a, w) -> WriterT w m a
+writer :: (Monad m) => (a, w) -> WriterT w m a
 writer = WriterT . return
 
 -- | Unwrap a writer computation as a (result, output) pair.
@@ -92,12 +95,33 @@
 --
 -- The 'return' function produces the output 'mempty', while @>>=@
 -- combines the outputs of the subcomputations using 'mappend'.
-newtype WriterT w m a = WriterT { runWriterT :: m (a, w) }
+newtype WriterT w m a = WriterT (m (a, w))
 
+instance (Eq w, Eq1 m, Eq a) => Eq (WriterT w m a) where
+    WriterT x == WriterT y = eq1 x y
+
+instance (Ord w, Ord1 m, Ord a) => Ord (WriterT w m a) where
+    compare (WriterT x) (WriterT y) = compare1 x y
+
+instance (Read w, Read1 m, Read a) => Read (WriterT w m a) where
+    readsPrec = readsData $ readsUnary1 "WriterT" WriterT
+
+instance (Show w, Show1 m, Show a) => Show (WriterT w m a) where
+    showsPrec d (WriterT m) = showsUnary1 "WriterT" d m
+
+instance (Eq w, Eq1 m) => Eq1 (WriterT w m) where eq1 = (==)
+instance (Ord w, Ord1 m) => Ord1 (WriterT w m) where compare1 = compare
+instance (Read w, Read1 m) => Read1 (WriterT w m) where readsPrec1 = readsPrec
+instance (Show w, Show1 m) => Show1 (WriterT w m) where showsPrec1 = showsPrec
+
+-- | The inverse of 'WriterT'.
+runWriterT :: WriterT w m a -> m (a, w)
+runWriterT (WriterT m) = m
+
 -- | Extract the output from a writer computation.
 --
 -- * @'execWriterT' m = 'liftM' 'snd' ('runWriterT' m)@
-execWriterT :: Monad m => WriterT w m a -> m w
+execWriterT :: (Monad m) => WriterT w m a -> m w
 execWriterT m = do
     ~(_, w) <- runWriterT m
     return w
@@ -112,6 +136,13 @@
 instance (Functor m) => Functor (WriterT w m) where
     fmap f = mapWriterT $ fmap $ \ ~(a, w) -> (f a, w)
 
+instance (Foldable f) => Foldable (WriterT w f) where
+    foldMap f = foldMap (f . fst) . runWriterT
+
+instance (Traversable f) => Traversable (WriterT w f) where
+    traverse f = fmap WriterT . traverse f' . runWriterT where
+       f' (a, b) = fmap (\ c -> (c, b)) (f a)
+
 instance (Monoid w, Applicative m) => Applicative (WriterT w m) where
     pure a  = WriterT $ pure (a, mempty)
     f <*> v = WriterT $ liftA2 k (runWriterT f) (runWriterT v)
@@ -144,13 +175,6 @@
 instance (Monoid w, MonadIO m) => MonadIO (WriterT w m) where
     liftIO = lift . liftIO
 
-instance Foldable f => Foldable (WriterT w f) where
-    foldMap f (WriterT a) = foldMap (f . fst) a
-
-instance Traversable f => Traversable (WriterT w f) where
-    traverse f (WriterT a) = WriterT <$> traverse f' a where
-       f' (a, b) = fmap (\c -> (c, b)) (f a)
-
 -- | @'tell' w@ is an action that produces the output @w@.
 tell :: (Monoid w, Monad m) => w -> WriterT w m ()
 tell w = writer ((), w)
@@ -158,7 +182,7 @@
 -- | @'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)@
+-- * @'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 m = WriterT $ do
     ~(a, w) <- runWriterT m
@@ -169,7 +193,7 @@
 --
 -- * @'listens' f m = 'liftM' (id *** f) ('listen' m)@
 --
--- * @'runWriterT' ('listens' f m) = 'liftM' (\\(a, w) -> ((a, f w), w)) ('runWriterT' 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 $ do
     ~(a, w) <- runWriterT m
@@ -179,7 +203,7 @@
 -- 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)@
+-- * @'runWriterT' ('pass' m) = 'liftM' (\\ ((a, f), w) -> (a, f w)) ('runWriterT' m)@
 pass :: (Monoid w, Monad m) => WriterT w m (a, w -> w) -> WriterT w m a
 pass m = WriterT $ do
     ~((a, f), w) <- runWriterT m
@@ -189,23 +213,21 @@
 -- applies the function @f@ to its output, leaving the return value
 -- unchanged.
 --
--- * @'censor' f m = 'pass' ('liftM' (\\x -> (x,f)) m)@
+-- * @'censor' f m = 'pass' ('liftM' (\\ x -> (x,f)) m)@
 --
--- * @'runWriterT' ('censor' f m) = 'liftM' (\\(a, w) -> (a, f w)) ('runWriterT' 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 $ do
     ~(a, w) <- runWriterT m
     return (a, f w)
 
 -- | Lift a @callCC@ operation to the new monad.
-liftCallCC :: (Monoid w) => ((((a,w) -> m (b,w)) -> m (a,w)) -> m (a,w)) ->
-    ((a -> WriterT w m b) -> WriterT w m a) -> WriterT w m a
+liftCallCC :: (Monoid w) => CallCC m (a,w) (b,w) -> CallCC (WriterT w m) a b
 liftCallCC callCC f = WriterT $
-    callCC $ \c ->
-    runWriterT (f (\a -> WriterT $ c (a, mempty)))
+    callCC $ \ c ->
+    runWriterT (f (\ a -> WriterT $ c (a, mempty)))
 
--- | Lift a @catchError@ operation to the new monad.
-liftCatch :: (m (a,w) -> (e -> m (a,w)) -> m (a,w)) ->
-    WriterT w m a -> (e -> WriterT w m a) -> WriterT w m a
-liftCatch catchError m h =
-    WriterT $ runWriterT m `catchError` \e -> runWriterT (h e)
+-- | Lift a @catchE@ operation to the new monad.
+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
@@ -12,12 +12,15 @@
 -- The strict 'WriterT' monad transformer, which adds collection of
 -- outputs (such as a count or string output) to a given monad.
 --
--- This version builds its output strictly; for a lazy version, see
--- "Control.Monad.Trans.Writer.Lazy", which has the same interface.
---
 -- 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; for a lazy version with
+-- 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.
 -----------------------------------------------------------------------------
 
 module Control.Monad.Trans.Writer.Strict (
@@ -29,6 +32,7 @@
     mapWriter,
     -- * The WriterT monad transformer
     WriterT(..),
+    runWriterT,
     execWriterT,
     mapWriterT,
     -- * Writer operations
@@ -44,11 +48,13 @@
 
 import Control.Monad.IO.Class
 import Control.Monad.Trans.Class
+import Data.Functor.Classes
 import Data.Functor.Identity
 
 import Control.Applicative
 import Control.Monad
 import Control.Monad.Fix
+import Control.Monad.Signatures
 import Data.Foldable (Foldable(foldMap))
 import Data.Monoid
 import Data.Traversable (Traversable(traverse))
@@ -62,7 +68,7 @@
 
 -- | Construct a writer computation from a (result, output) pair.
 -- (The inverse of 'runWriter'.)
-writer :: Monad m => (a, w) -> WriterT w m a
+writer :: (Monad m) => (a, w) -> WriterT w m a
 writer = WriterT . return
 
 -- | Unwrap a writer computation as a (result, output) pair.
@@ -92,12 +98,33 @@
 --
 -- The 'return' function produces the output 'mempty', while @>>=@
 -- combines the outputs of the subcomputations using 'mappend'.
-newtype WriterT w m a = WriterT { runWriterT :: m (a, w) }
+newtype WriterT w m a = WriterT (m (a, w))
 
+instance (Eq w, Eq1 m, Eq a) => Eq (WriterT w m a) where
+    WriterT x == WriterT y = eq1 x y
+
+instance (Ord w, Ord1 m, Ord a) => Ord (WriterT w m a) where
+    compare (WriterT x) (WriterT y) = compare1 x y
+
+instance (Read w, Read1 m, Read a) => Read (WriterT w m a) where
+    readsPrec = readsData $ readsUnary1 "WriterT" WriterT
+
+instance (Show w, Show1 m, Show a) => Show (WriterT w m a) where
+    showsPrec d (WriterT m) = showsUnary1 "WriterT" d m
+
+instance (Eq w, Eq1 m) => Eq1 (WriterT w m) where eq1 = (==)
+instance (Ord w, Ord1 m) => Ord1 (WriterT w m) where compare1 = compare
+instance (Read w, Read1 m) => Read1 (WriterT w m) where readsPrec1 = readsPrec
+instance (Show w, Show1 m) => Show1 (WriterT w m) where showsPrec1 = showsPrec
+
+-- | The inverse of 'WriterT'.
+runWriterT :: WriterT w m a -> m (a, w)
+runWriterT (WriterT m) = m
+
 -- | Extract the output from a writer computation.
 --
 -- * @'execWriterT' m = 'liftM' 'snd' ('runWriterT' m)@
-execWriterT :: Monad m => WriterT w m a -> m w
+execWriterT :: (Monad m) => WriterT w m a -> m w
 execWriterT m = do
     (_, w) <- runWriterT m
     return w
@@ -113,11 +140,11 @@
     fmap f = mapWriterT $ fmap $ \ (a, w) -> (f a, w)
 
 instance (Foldable f) => Foldable (WriterT w f) where
-    foldMap f (WriterT a) = foldMap (f . fst) a
+    foldMap f = foldMap (f . fst) . runWriterT
 
 instance (Traversable f) => Traversable (WriterT w f) where
-    traverse f (WriterT a) = WriterT <$> traverse f' a where
-       f' (a, b) = fmap (\c -> (c, b)) (f a)
+    traverse f = fmap WriterT . traverse f' . runWriterT where
+       f' (a, b) = fmap (\ c -> (c, b)) (f a)
 
 instance (Monoid w, Applicative m) => Applicative (WriterT w m) where
     pure a  = WriterT $ pure (a, mempty)
@@ -129,7 +156,7 @@
     m <|> n = WriterT $ runWriterT m <|> runWriterT n
 
 instance (Monoid w, Monad m) => Monad (WriterT w m) where
-    return a = WriterT $ return (a, mempty)
+    return a = writer (a, mempty)
     m >>= k  = WriterT $ do
         (a, w)  <- runWriterT m
         (b, w') <- runWriterT (k a)
@@ -153,12 +180,12 @@
 
 -- | @'tell' w@ is an action that produces the output @w@.
 tell :: (Monoid w, Monad m) => w -> WriterT w m ()
-tell w = WriterT $ return ((), w)
+tell w = writer ((), w)
 
 -- | @'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)@
+-- * @'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 m = WriterT $ do
     (a, w) <- runWriterT m
@@ -169,7 +196,7 @@
 --
 -- * @'listens' f m = 'liftM' (id *** f) ('listen' m)@
 --
--- * @'runWriterT' ('listens' f m) = 'liftM' (\\(a, w) -> ((a, f w), w)) ('runWriterT' 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 $ do
     (a, w) <- runWriterT m
@@ -179,7 +206,7 @@
 -- 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)@
+-- * @'runWriterT' ('pass' m) = 'liftM' (\\ ((a, f), w) -> (a, f w)) ('runWriterT' m)@
 pass :: (Monoid w, Monad m) => WriterT w m (a, w -> w) -> WriterT w m a
 pass m = WriterT $ do
     ((a, f), w) <- runWriterT m
@@ -189,23 +216,21 @@
 -- applies the function @f@ to its output, leaving the return value
 -- unchanged.
 --
--- * @'censor' f m = 'pass' ('liftM' (\\x -> (x,f)) m)@
+-- * @'censor' f m = 'pass' ('liftM' (\\ x -> (x,f)) m)@
 --
--- * @'runWriterT' ('censor' f m) = 'liftM' (\\(a, w) -> (a, f w)) ('runWriterT' 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 $ do
     (a, w) <- runWriterT m
     return (a, f w)
 
 -- | Lift a @callCC@ operation to the new monad.
-liftCallCC :: (Monoid w) => ((((a,w) -> m (b,w)) -> m (a,w)) -> m (a,w)) ->
-    ((a -> WriterT w m b) -> WriterT w m a) -> WriterT w m a
+liftCallCC :: (Monoid w) => CallCC m (a,w) (b,w) -> CallCC (WriterT w m) a b
 liftCallCC callCC f = WriterT $
-    callCC $ \c ->
-    runWriterT (f (\a -> WriterT $ c (a, mempty)))
+    callCC $ \ c ->
+    runWriterT (f (\ a -> WriterT $ c (a, mempty)))
 
--- | Lift a @catchError@ operation to the new monad.
-liftCatch :: (m (a,w) -> (e -> m (a,w)) -> m (a,w)) ->
-    WriterT w m a -> (e -> WriterT w m a) -> WriterT w m a
-liftCatch catchError m h =
-    WriterT $ runWriterT m `catchError` \e -> runWriterT (h e)
+-- | Lift a @catchE@ operation to the new monad.
+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/Classes.hs b/Data/Functor/Classes.hs
new file mode 100644
--- /dev/null
+++ b/Data/Functor/Classes.hs
@@ -0,0 +1,116 @@
+-- |
+-- Module      :  Data.Functor.Classes
+-- Copyright   :  (c) Ross Paterson 2013
+-- License     :  BSD-style (see the file LICENSE)
+--
+-- Maintainer  :  ross@soi.city.ac.uk
+-- Stability   :  experimental
+-- Portability :  portable
+--
+-- Prelude classes, lifted to unary type constructors.
+
+module Data.Functor.Classes (
+    -- * Liftings of Prelude classes
+    Eq1(..),
+    Ord1(..),
+    Read1(..),
+    Show1(..),
+    -- * Helper functions
+    readsData,
+    readsUnary,
+    readsUnary1,
+    readsBinary1,
+    showsUnary,
+    showsUnary1,
+    showsBinary1,
+  ) where
+
+-- | Lifting of the 'Eq' class to unary type constructors.
+class Eq1 f where
+    eq1 :: (Eq a) => f a -> f a -> Bool
+
+-- | Lifting of the 'Ord' class to unary type constructors.
+class (Eq1 f) => Ord1 f where
+    compare1 :: (Ord a) => f a -> f a -> Ordering
+
+-- | Lifting of the 'Read' class to unary type constructors.
+class Read1 f where
+    readsPrec1 :: (Read a) => Int -> ReadS (f a)
+
+-- | Lifting of the 'Show' class to unary type constructors.
+class Show1 f where
+    showsPrec1 :: (Show a) => Int -> f a -> ShowS
+
+-- Instances for Prelude type constructors
+
+instance Eq1 Maybe where eq1 = (==)
+instance Ord1 Maybe where compare1 = compare
+instance Read1 Maybe where readsPrec1 = readsPrec
+instance Show1 Maybe where showsPrec1 = showsPrec
+
+instance Eq1 [] where eq1 = (==)
+instance Ord1 [] where compare1 = compare
+instance Read1 [] where readsPrec1 = readsPrec
+instance Show1 [] where showsPrec1 = showsPrec
+
+instance (Eq a) => Eq1 ((,) a) where eq1 = (==)
+instance (Ord a) => Ord1 ((,) a) where compare1 = compare
+instance (Read a) => Read1 ((,) a) where readsPrec1 = readsPrec
+instance (Show a) => Show1 ((,) a) where showsPrec1 = showsPrec
+
+instance (Eq a) => Eq1 (Either a) where eq1 = (==)
+instance (Ord a) => Ord1 (Either a) where compare1 = compare
+instance (Read a) => Read1 (Either a) where readsPrec1 = readsPrec
+instance (Show a) => Show1 (Either a) where showsPrec1 = showsPrec
+
+-- Building blocks
+
+-- | @'readsData' p d@ is a parser for datatypes where each alternative
+-- begins with a data constructor.  It parses the constructor and
+-- passes it to @p@.  Parsers for various constructors can be constructed
+-- with 'readsUnary', 'readsUnary1' and 'readsBinary1', and combined with
+-- @mappend@ from the @Monoid@ class.
+readsData :: (String -> ReadS a) -> Int -> ReadS a
+readsData reader d =
+    readParen (d > 10) $ \ r -> [res | (kw,s) <- lex r, res <- reader kw s]
+
+-- | @'readsUnary' n c n'@ matches the name of a unary data constructor
+-- and then parses its argument using 'readsPrec'.
+readsUnary :: (Read a) => String -> (a -> t) -> String -> ReadS t
+readsUnary name cons kw s =
+    [(cons x,t) | kw == name, (x,t) <- readsPrec 11 s]
+
+-- | @'readsUnary1' n c n'@ matches the name of a unary data constructor
+-- and then parses its argument using 'readsPrec1'.
+readsUnary1 :: (Read1 f, Read a) => String -> (f a -> t) -> String -> ReadS t
+readsUnary1 name cons kw s =
+    [(cons x,t) | kw == name, (x,t) <- readsPrec1 11 s]
+
+-- | @'readsBinary1' n c n'@ matches the name of a binary data constructor
+-- and then parses its arguments using 'readsPrec1'.
+readsBinary1 :: (Read1 f, Read1 g, Read a) =>
+    String -> (f a -> g a -> t) -> String -> ReadS t
+readsBinary1 name cons kw s =
+    [(cons x y,u) | kw == name,
+        (x,t) <- readsPrec1 11 s, (y,u) <- readsPrec1 11 t]
+
+-- | @'showsUnary' n d x@ produces the string representation of a unary data
+-- constructor with name @n@ and argument @x@, in precedence context @d@.
+showsUnary :: (Show a) => String -> Int -> a -> ShowS
+showsUnary name d x = showParen (d > 10) $
+    showString name . showChar ' ' . showsPrec 11 x
+
+-- | @'showsUnary1' n d x@ produces the string representation of a unary data
+-- constructor with name @n@ and argument @x@, in precedence context @d@.
+showsUnary1 :: (Show1 f, Show a) => String -> Int -> f a -> ShowS
+showsUnary1 name d x = showParen (d > 10) $
+    showString name . showChar ' ' . showsPrec1 11 x
+
+-- | @'showsBinary1' n d x@ produces the string representation of a binary
+-- data constructor with name @n@ and arguments @x@ and @y@, in precedence
+-- context @d@.
+showsBinary1 :: (Show1 f, Show1 g, Show a) =>
+    String -> Int -> f a -> g a -> ShowS
+showsBinary1 name d x y = showParen (d > 10) $
+    showString name . showChar ' ' . showsPrec1 11 x .
+        showChar ' ' . showsPrec1 11 y
diff --git a/Data/Functor/Compose.hs b/Data/Functor/Compose.hs
--- a/Data/Functor/Compose.hs
+++ b/Data/Functor/Compose.hs
@@ -11,16 +11,67 @@
 
 module Data.Functor.Compose (
     Compose(..),
-   ) where
+    getCompose,
+  ) where
 
+import Data.Functor.Classes
+
 import Control.Applicative
 import Data.Foldable (Foldable(foldMap))
 import Data.Traversable (Traversable(traverse))
 
+infixr 9 `Compose`
+
 -- | Right-to-left composition of functors.
 -- The composition of applicative functors is always applicative,
 -- but the composition of monads is not always a monad.
-newtype Compose f g a = Compose { getCompose :: f (g a) }
+newtype Compose f g a = Compose (f (g a))
+
+-- | Inverse of 'Compose'.
+getCompose :: Compose f g a -> f (g a)
+getCompose (Compose x) = x
+
+-- Instances of Prelude classes
+
+-- kludge to get type with the same instances as g a
+newtype Apply g a = Apply (g a)
+
+getApply :: Apply g a -> g a
+getApply (Apply x) = x
+
+instance (Eq1 g, Eq a) => Eq (Apply g a) where
+    Apply x == Apply y = eq1 x y
+
+instance (Ord1 g, Ord a) => Ord (Apply g a) where
+    compare (Apply x) (Apply y) = compare1 x y
+
+instance (Read1 g, Read a) => Read (Apply g a) where
+    readsPrec d s = [(Apply a, t) | (a, t) <- readsPrec1 d s]
+
+instance (Show1 g, Show a) => Show (Apply g a) where
+    showsPrec d (Apply x) = showsPrec1 d x
+
+instance (Functor f, Eq1 f, Eq1 g, Eq a) => Eq (Compose f g a) where
+    Compose x == Compose y = eq1 (fmap Apply x) (fmap Apply y)
+
+instance (Functor f, Ord1 f, Ord1 g, Ord a) => Ord (Compose f g a) where
+    compare (Compose x) (Compose y) = compare1 (fmap Apply x) (fmap Apply y)
+
+instance (Functor f, Read1 f, Read1 g, Read a) => Read (Compose f g a) where
+    readsPrec = readsData $ readsUnary1 "Compose" (Compose . fmap getApply)
+
+instance (Functor f, Show1 f, Show1 g, Show a) => Show (Compose f g a) where
+    showsPrec d (Compose x) = showsUnary1 "Compose" d (fmap Apply x)
+
+instance (Functor f, Eq1 f, Eq1 g) => Eq1 (Compose f g) where eq1 = (==)
+instance (Functor f, Ord1 f, Ord1 g) => Ord1 (Compose f g) where
+    compare1 = compare
+instance (Functor f, Read1 f, Read1 g) => Read1 (Compose f g) where
+    readsPrec1 = readsPrec
+instance (Functor f, Show1 f, Show1 g) => Show1 (Compose f g) where
+    showsPrec1 = showsPrec
+
+-- Functor instances
 
 instance (Functor f, Functor g) => Functor (Compose f g) where
     fmap f (Compose x) = Compose (fmap (fmap f) x)
diff --git a/Data/Functor/Constant.hs b/Data/Functor/Constant.hs
--- a/Data/Functor/Constant.hs
+++ b/Data/Functor/Constant.hs
@@ -11,24 +11,37 @@
 
 module Data.Functor.Constant (
     Constant(..),
-   ) where
+    getConstant,
+  ) where
 
+import Data.Functor.Classes
+
 import Control.Applicative
 import Data.Foldable (Foldable(foldMap))
 import Data.Monoid (Monoid(..))
 import Data.Traversable (Traversable(traverse))
 
 -- | Constant functor.
-newtype Constant a b = Constant { getConstant :: a }
+newtype Constant a b = Constant a
+    deriving (Eq, Ord, Read, Show)
 
+-- | Inverse of 'Constant'.
+getConstant :: Constant a b -> a
+getConstant (Constant x) = x
+
+instance (Eq a) => Eq1 (Constant a) where eq1 = (==)
+instance (Ord a) => Ord1 (Constant a) where compare1 = compare
+instance (Read a) => Read1 (Constant a) where readsPrec1 = readsPrec
+instance (Show a) => Show1 (Constant a) where showsPrec1 = showsPrec
+
 instance Functor (Constant a) where
-    fmap f (Constant x) = Constant x
+    fmap _ (Constant x) = Constant x
 
 instance Foldable (Constant a) where
-    foldMap f (Constant x) = mempty
+    foldMap _ (Constant _) = mempty
 
 instance Traversable (Constant a) where
-    traverse f (Constant x) = pure (Constant x)
+    traverse _ (Constant x) = pure (Constant x)
 
 instance (Monoid a) => Applicative (Constant a) where
     pure _ = Constant mempty
diff --git a/Data/Functor/Identity.hs b/Data/Functor/Identity.hs
--- a/Data/Functor/Identity.hs
+++ b/Data/Functor/Identity.hs
@@ -22,16 +22,28 @@
 
 module Data.Functor.Identity (
     Identity(..),
-   ) where
+    runIdentity,
+  ) where
 
+import Data.Functor.Classes
+
 import Control.Applicative
-import Control.Monad
 import Control.Monad.Fix
 import Data.Foldable (Foldable(foldMap))
 import Data.Traversable (Traversable(traverse))
 
--- | Identity functor and monad.
-newtype Identity a = Identity { runIdentity :: a }
+-- | Identity functor and monad. (a non-strict monad)
+newtype Identity a = Identity a
+    deriving (Eq, Ord, Read, Show)
+
+-- | Inverse of 'Identity'.
+runIdentity :: Identity a -> a
+runIdentity (Identity x) = x
+
+instance Eq1 Identity where eq1 = (==)
+instance Ord1 Identity where compare1 = compare
+instance Read1 Identity where readsPrec1 = readsPrec
+instance Show1 Identity where showsPrec1 = showsPrec
 
 -- ---------------------------------------------------------------------------
 -- Identity instances for Functor and Monad
diff --git a/Data/Functor/Product.hs b/Data/Functor/Product.hs
--- a/Data/Functor/Product.hs
+++ b/Data/Functor/Product.hs
@@ -11,17 +11,36 @@
 
 module Data.Functor.Product (
     Product(..),
-   ) where
+  ) where
 
 import Control.Applicative
 import Control.Monad (MonadPlus(..))
 import Control.Monad.Fix (MonadFix(..))
 import Data.Foldable (Foldable(foldMap))
+import Data.Functor.Classes
 import Data.Monoid (mappend)
 import Data.Traversable (Traversable(traverse))
 
 -- | Lifted product of functors.
 data Product f g a = Pair (f a) (g a)
+
+instance (Eq1 f, Eq1 g, Eq a) => Eq (Product f g a) where
+    Pair x1 y1 == Pair x2 y2 = eq1 x1 x2 && eq1 y1 y2
+
+instance (Ord1 f, Ord1 g, Ord a) => Ord (Product f g a) where
+    compare (Pair x1 y1) (Pair x2 y2) =
+        compare1 x1 x2 `mappend` compare1 y1 y2
+
+instance (Read1 f, Read1 g, Read a) => Read (Product f g a) where
+    readsPrec = readsData $ readsBinary1 "Pair" Pair
+
+instance (Show1 f, Show1 g, Show a) => Show (Product f g a) where
+    showsPrec d (Pair x y) = showsBinary1 "Pair" d x y
+
+instance (Eq1 f, Eq1 g) => Eq1 (Product f g) where eq1 = (==)
+instance (Ord1 f, Ord1 g) => Ord1 (Product f g) where compare1 = compare
+instance (Read1 f, Read1 g) => Read1 (Product f g) where readsPrec1 = readsPrec
+instance (Show1 f, Show1 g) => Show1 (Product f g) where showsPrec1 = showsPrec
 
 instance (Functor f, Functor g) => Functor (Product f g) where
     fmap f (Pair x y) = Pair (fmap f x) (fmap f y)
diff --git a/Data/Functor/Reverse.hs b/Data/Functor/Reverse.hs
--- a/Data/Functor/Reverse.hs
+++ b/Data/Functor/Reverse.hs
@@ -10,9 +10,13 @@
 -- Making functors whose elements are notionally in the reverse order
 -- from the original functor.
 
-module Data.Functor.Reverse where
+module Data.Functor.Reverse (
+    Reverse(..),
+    getReverse,
+  ) where
 
 import Control.Applicative.Backwards
+import Data.Functor.Classes
 
 import Prelude hiding (foldr, foldr1, foldl, foldl1)
 import Control.Applicative
@@ -22,7 +26,28 @@
 
 -- | 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 }
+newtype Reverse f a = Reverse (f a)
+
+-- | Inverse of 'Reverse'.
+getReverse :: Reverse f a -> f a
+getReverse (Reverse x) = x
+
+instance (Eq1 f, Eq a) => Eq (Reverse f a) where
+    Reverse x == Reverse y = eq1 x y
+
+instance (Ord1 f, Ord a) => Ord (Reverse f a) where
+    compare (Reverse x) (Reverse y) = compare1 x y
+
+instance (Read1 f, Read a) => Read (Reverse f a) where
+    readsPrec = readsData $ readsUnary1 "Reverse" Reverse
+
+instance (Show1 f, Show a) => Show (Reverse f a) where
+    showsPrec d (Reverse x) = showsUnary1 "Reverse" d x
+
+instance (Eq1 f) => Eq1 (Reverse f) where eq1 = (==)
+instance (Ord1 f) => Ord1 (Reverse f) where compare1 = compare
+instance (Read1 f) => Read1 (Reverse f) where readsPrec1 = readsPrec
+instance (Show1 f) => Show1 (Reverse f) where showsPrec1 = showsPrec
 
 -- | Derived instance.
 instance (Functor f) => Functor (Reverse f) where
diff --git a/Data/Functor/Sum.hs b/Data/Functor/Sum.hs
new file mode 100644
--- /dev/null
+++ b/Data/Functor/Sum.hs
@@ -0,0 +1,59 @@
+-- |
+-- Module      :  Data.Functor.Sum
+-- Copyright   :  (c) Ross Paterson 2014
+-- License     :  BSD-style (see the file LICENSE)
+--
+-- Maintainer  :  ross@soi.city.ac.uk
+-- Stability   :  experimental
+-- Portability :  portable
+--
+-- Sums, lifted to functors.
+
+module Data.Functor.Sum (
+    Sum(..),
+  ) where
+
+import Control.Applicative
+import Data.Foldable (Foldable(foldMap))
+import Data.Functor.Classes
+import Data.Monoid (mappend)
+import Data.Traversable (Traversable(traverse))
+
+-- | Lifted sum of functors.
+data Sum f g a = InL (f a) | InR (g a)
+
+instance (Eq1 f, Eq1 g, Eq a) => Eq (Sum f g a) where
+    InL x1 == InL x2 = eq1 x1 x2
+    InR y1 == InR y2 = eq1 y1 y2
+    _ == _ = False
+
+instance (Ord1 f, Ord1 g, Ord a) => Ord (Sum f g a) where
+    compare (InL x1) (InL x2) = compare1 x1 x2
+    compare (InL _) (InR _) = LT
+    compare (InR _) (InL _) = GT
+    compare (InR y1) (InR y2) = compare1 y1 y2
+
+instance (Read1 f, Read1 g, Read a) => Read (Sum f g a) where
+    readsPrec = readsData $
+        readsUnary1 "InL" InL `mappend` readsUnary1 "InR" InR
+
+instance (Show1 f, Show1 g, Show a) => Show (Sum f g a) where
+    showsPrec d (InL x) = showsUnary1 "InL" d x
+    showsPrec d (InR y) = showsUnary1 "InR" d y
+
+instance (Eq1 f, Eq1 g) => Eq1 (Sum f g) where eq1 = (==)
+instance (Ord1 f, Ord1 g) => Ord1 (Sum f g) where compare1 = compare
+instance (Read1 f, Read1 g) => Read1 (Sum f g) where readsPrec1 = readsPrec
+instance (Show1 f, Show1 g) => Show1 (Sum f g) where showsPrec1 = showsPrec
+
+instance (Functor f, Functor g) => Functor (Sum f g) where
+    fmap f (InL x) = InL (fmap f x)
+    fmap f (InR y) = InR (fmap f y)
+
+instance (Foldable f, Foldable g) => Foldable (Sum f g) where
+    foldMap f (InL x) = foldMap f x
+    foldMap f (InR y) = foldMap f y
+
+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
diff --git a/changelog b/changelog
new file mode 100644
--- /dev/null
+++ b/changelog
@@ -0,0 +1,58 @@
+-*-change-log-*-
+
+0.4.0.0 Ross Paterson <ross@soi.city.ac.uk> May 2014
+	* Added Sum type
+	* Added modify', a strict version of modify, to the state monads
+	* Added ExceptT and deprecated ErrorT
+	* Added infixr 9 `Compose` to match (.)
+	* Added Eq, Ord, Read and Show instances where possible
+	* Replaced record syntax for newtypes with separate inverse functions
+	* Added delimited continuation functions to ContT
+	* Added instance Alternative IO to ErrorT
+	* Handled disappearance of Control.Monad.Instances
+
+0.3.0.0 Ross Paterson <ross@soi.city.ac.uk> Mar 2012
+	* Added type synonyms for signatures of complex operations
+	* Generalized state, reader and writer constructor functions
+	* Added Lift, Backwards/Reverse
+	* Added MonadFix instances for IdentityT and MaybeT
+	* Added Foldable and Traversable instances
+	* Added Monad instances for Product
+
+0.2.2.1 Ross Paterson <ross@soi.city.ac.uk> Oct 2013
+	* Backport of fix for disappearance of Control.Monad.Instances
+
+0.2.2.0 Ross Paterson <ross@soi.city.ac.uk> Sep 2010
+	* Handled move of Either instances to base package
+
+0.2.1.0 Ross Paterson <ross@soi.city.ac.uk> Apr 2010
+	* Added Alternative instance for Compose
+	* Added Data.Functor.Product
+
+0.2.0.0 Ross Paterson <ross@soi.city.ac.uk> Mar 2010
+	* Added Constant and Compose
+	* Renamed modules to avoid clash with mtl
+	* Removed Monad constraint from Monad instance for ContT
+
+0.1.4.0 Ross Paterson <ross@soi.city.ac.uk> Mar 2009
+	* Adjusted lifting of Identity and Maybe transformers
+
+0.1.3.0 Ross Paterson <ross@soi.city.ac.uk> Mar 2009
+	* Added IdentityT transformer
+	* Added Applicative and Alternative instances for (Either e)
+
+0.1.1.0 Ross Paterson <ross@soi.city.ac.uk> Jan 2009
+	* Made all Functor instances assume Functor
+
+0.1.0.1 Ross Paterson <ross@soi.city.ac.uk> Jan 2009
+	* Adjusted dependencies
+
+0.1.0.0 Ross Paterson <ross@soi.city.ac.uk> Jan 2009
+	* Two versions of lifting of callcc through StateT
+	* Added Applicative instances
+
+0.0.1.0 Ross Paterson <ross@soi.city.ac.uk> Jan 2009
+	* Added constructors state, etc for simple monads
+
+0.0.0.0 Ross Paterson <ross@soi.city.ac.uk> Jan 2009
+	* Split Haskell 98 transformers from the mtl
diff --git a/transformers.cabal b/transformers.cabal
--- a/transformers.cabal
+++ b/transformers.cabal
@@ -1,5 +1,5 @@
 name:         transformers
-version:      0.3.0.0
+version:      0.4.0.0
 license:      BSD3
 license-file: LICENSE
 author:       Andy Gill, Ross Paterson
@@ -16,16 +16,21 @@
     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
       transformers.
     .
-    It can be used on its own in portable Haskell code, or with the monad
-    classes in the @mtl@ or @monads-tf@ packages, which automatically
-    lift operations introduced by monad transformers through other
-    transformers.
+    The package can be used on its own in portable Haskell code, in
+    which case operations need to be manually lifted through transformer
+    stacks (see "Control.Monad.Trans.Class" for some examples).
+    Alternatively, it can be used with the non-portable monad classes in
+    the @mtl@ or @monads-tf@ packages, which automatically lift operations
+    introduced by monad transformers through other transformers.
 build-type: Simple
+extra-source-files:
+    changelog
 cabal-version: >= 1.6
 
 source-repository head
@@ -45,8 +50,10 @@
     Control.Applicative.Backwards
     Control.Applicative.Lift
     Control.Monad.IO.Class
+    Control.Monad.Signatures
     Control.Monad.Trans.Class
     Control.Monad.Trans.Cont
+    Control.Monad.Trans.Except
     Control.Monad.Trans.Error
     Control.Monad.Trans.Identity
     Control.Monad.Trans.List
@@ -61,8 +68,10 @@
     Control.Monad.Trans.Writer
     Control.Monad.Trans.Writer.Lazy
     Control.Monad.Trans.Writer.Strict
+    Data.Functor.Classes
     Data.Functor.Compose
     Data.Functor.Constant
     Data.Functor.Identity
     Data.Functor.Product
     Data.Functor.Reverse
+    Data.Functor.Sum
