diff --git a/Control/Monad/Cont.hs b/Control/Monad/Cont.hs
--- a/Control/Monad/Cont.hs
+++ b/Control/Monad/Cont.hs
@@ -1,16 +1,13 @@
-{-# LANGUAGE UndecidableInstances #-}
--- Search for UndecidableInstances to see why this is needed
-
 {- |
 Module      :  Control.Monad.Cont
 Copyright   :  (c) The University of Glasgow 2001,
                (c) Jeff Newbern 2003-2007,
                (c) Andriy Palamarchuk 2007
-License     :  BSD-style (see the file libraries/base/LICENSE)
+License     :  BSD-style (see the file LICENSE)
 
 Maintainer  :  libraries@haskell.org
 Stability   :  experimental
-Portability :  non-portable (multi-parameter type classes)
+Portability :  portable
 
 [Computation type:] Computations which can be interrupted and resumed.
 
@@ -52,10 +49,14 @@
 -}
 
 module Control.Monad.Cont (
-    module Control.Monad.Cont.Class,
-    Cont(..),
+    -- * MonadCont class
+    MonadCont(..),
+    -- * The Cont monad
+    Cont,
+    runCont,
     mapCont,
     withCont,
+    -- * The ContT monad transformer
     ContT(..),
     mapContT,
     withContT,
@@ -71,92 +72,12 @@
     -- $ContTExample
   ) where
 
-import Control.Monad
 import Control.Monad.Cont.Class
-import Control.Monad.Reader.Class
-import Control.Monad.State.Class
-import Control.Monad.Trans
 
-{- |
-Continuation monad.
-@Cont r a@ is a CPS computation that produces an intermediate result
-of type @a@ within a CPS computation whose final result type is @r@.
-
-The @return@ function simply creates a continuation which passes the value on.
-
-The @>>=@ operator adds the bound function into the continuation chain.
--}
-newtype Cont r a = Cont {
-
-    {- | Runs a CPS computation, returns its result after applying
-    the final continuation to it.
-    Parameters:
-
-    * a continuation computation (@Cont@).
-
-    * the final continuation, which produces the final result (often @id@).
-    -}
-    runCont :: (a -> r) -> r
-}
-
-mapCont :: (r -> r) -> Cont r a -> Cont r a
-mapCont f m = Cont $ f . runCont m
-
-withCont :: ((b -> r) -> (a -> r)) -> Cont r a -> Cont r b
-withCont f m = Cont $ runCont m . f
-
-instance Functor (Cont r) where
-    fmap f m = Cont $ \c -> runCont m (c . f)
-
-instance Monad (Cont r) where
-    return a = Cont ($ a)
-    m >>= k  = Cont $ \c -> runCont m $ \a -> runCont (k a) c
-
-instance MonadCont (Cont r) where
-    callCC f = Cont $ \c -> runCont (f (\a -> Cont $ \_ -> c a)) c
-
-{- |
-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 }
-
-mapContT :: (m r -> m r) -> ContT r m a -> ContT r m a
-mapContT f m = ContT $ f . runContT m
-
-withContT :: ((b -> m r) -> (a -> m r)) -> ContT r m a -> ContT r m b
-withContT f m = ContT $ runContT m . f
-
-instance (Monad m) => Functor (ContT r m) where
-    fmap f m = ContT $ \c -> runContT m (c . f)
-
-instance (Monad m) => Monad (ContT r m) where
-    return a = ContT ($ a)
-    m >>= k  = ContT $ \c -> runContT m (\a -> runContT (k a) c)
-
-instance (Monad m) => MonadCont (ContT r m) where
-    callCC f = ContT $ \c -> runContT (f (\a -> ContT $ \_ -> c a)) c
-
--- ---------------------------------------------------------------------------
--- Instances for other mtl transformers
-
-instance MonadTrans (ContT r) where
-    lift m = ContT (m >>=)
-
-instance (MonadIO m) => MonadIO (ContT r m) where
-    liftIO = lift . liftIO
-
--- Needs UndecidableInstances
-instance (MonadReader r' m) => MonadReader r' (ContT r m) where
-    ask       = lift ask
-    local f m = ContT $ \c -> do
-        r <- ask
-        local f (runContT m (local (const r) . c))
+import Control.Monad.Trans
+import Control.Monad.Trans.Cont
 
--- Needs UndecidableInstances
-instance (MonadState s m) => MonadState s (ContT r m) where
-    get = lift get
-    put = lift . put
+import Control.Monad
 
 {- $simpleContExample
 Calculating length of a list continuation-style:
@@ -203,15 +124,15 @@
 (1) Runs an anonymous 'Cont' block and extracts value from it with
 @(\`runCont\` id)@. Here @id@ is the continuation, passed to the @Cont@ block.
 
-(1) Binds @response@ to the result of the following 'callCC' block,
+(1) Binds @response@ to the result of the following 'Control.Monad.Cont.Class.callCC' block,
 binds @exit@ to the continuation.
 
 (1) Validates @name@.
-This approach illustrates advantage of using 'callCC' over @return@.
+This approach illustrates advantage of using 'Control.Monad.Cont.Class.callCC' over @return@.
 We pass the continuation to @validateName@,
 and interrupt execution of the @Cont@ block from /inside/ of @validateName@.
 
-(1) Returns the welcome message from the @callCC@ block.
+(1) Returns the welcome message from the 'Control.Monad.Cont.Class.callCC' block.
 This line is not executed if @validateName@ fails.
 
 (1) Returns from the @Cont@ block.
diff --git a/Control/Monad/Cont/Class.hs b/Control/Monad/Cont/Class.hs
--- a/Control/Monad/Cont/Class.hs
+++ b/Control/Monad/Cont/Class.hs
@@ -1,16 +1,13 @@
-{-# LANGUAGE UndecidableInstances #-}
--- Search for UndecidableInstances to see why this is needed
-
 {- |
 Module      :  Control.Monad.Cont.Class
 Copyright   :  (c) The University of Glasgow 2001,
                (c) Jeff Newbern 2003-2007,
                (c) Andriy Palamarchuk 2007
-License     :  BSD-style (see the file libraries/base/LICENSE)
+License     :  BSD-style (see the file LICENSE)
 
 Maintainer  :  libraries@haskell.org
 Stability   :  experimental
-Portability :  non-portable (multi-parameter type classes)
+Portability :  portable
 
 [Computation type:] Computations which can be interrupted and resumed.
 
@@ -55,6 +52,23 @@
     MonadCont(..),
   ) where
 
+import Control.Monad.Trans.Cont (ContT)
+import qualified Control.Monad.Trans.Cont as ContT
+import Control.Monad.Trans.Error as Error
+import Control.Monad.Trans.Identity as Identity
+import Control.Monad.Trans.List as List
+import Control.Monad.Trans.Maybe as Maybe
+import Control.Monad.Trans.Reader as Reader
+import Control.Monad.Trans.RWS.Lazy as LazyRWS
+import Control.Monad.Trans.RWS.Strict as StrictRWS
+import Control.Monad.Trans.State.Lazy as LazyState
+import Control.Monad.Trans.State.Strict as StrictState
+import Control.Monad.Trans.Writer.Lazy as LazyWriter
+import Control.Monad.Trans.Writer.Strict as StrictWriter
+
+import Control.Monad
+import Data.Monoid
+
 class (Monad m) => MonadCont m where
     {- | @callCC@ (call-with-current-continuation)
     calls a function with the current continuation as its argument.
@@ -76,3 +90,41 @@
     -}
     callCC :: ((a -> m b) -> m a) -> m a
 
+instance MonadCont (ContT r m) where
+    callCC = ContT.callCC
+
+-- ---------------------------------------------------------------------------
+-- Instances for other mtl transformers
+
+instance (Error e, MonadCont m) => MonadCont (ErrorT e m) where
+    callCC = Error.liftCallCC callCC
+
+instance (MonadCont m) => MonadCont (IdentityT m) where
+    callCC = Identity.liftCallCC callCC
+
+instance (MonadCont m) => MonadCont (ListT m) where
+    callCC = List.liftCallCC callCC
+
+instance (MonadCont m) => MonadCont (MaybeT m) where
+    callCC = Maybe.liftCallCC callCC
+
+instance (MonadCont m) => MonadCont (ReaderT r m) where
+    callCC = Reader.liftCallCC callCC
+
+instance (Monoid w, MonadCont m) => MonadCont (LazyRWS.RWST r w s m) where
+    callCC = LazyRWS.liftCallCC' callCC
+
+instance (Monoid w, MonadCont m) => MonadCont (StrictRWS.RWST r w s m) where
+    callCC = StrictRWS.liftCallCC' callCC
+
+instance (MonadCont m) => MonadCont (LazyState.StateT s m) where
+    callCC = LazyState.liftCallCC' callCC
+
+instance (MonadCont m) => MonadCont (StrictState.StateT s m) where
+    callCC = StrictState.liftCallCC' callCC
+
+instance (Monoid w, MonadCont m) => MonadCont (LazyWriter.WriterT w m) where
+    callCC = LazyWriter.liftCallCC callCC
+
+instance (Monoid w, MonadCont m) => MonadCont (StrictWriter.WriterT w m) where
+    callCC = StrictWriter.liftCallCC callCC
diff --git a/Control/Monad/Error.hs b/Control/Monad/Error.hs
--- a/Control/Monad/Error.hs
+++ b/Control/Monad/Error.hs
@@ -1,16 +1,9 @@
--- Undecidable instances needed for the same reasons as in Reader, State etc:
-{-# LANGUAGE UndecidableInstances #-}
--- De-orphaning this module is tricky:
-{-# OPTIONS_GHC -fno-warn-orphans #-}
--- To handle instances moved to base:
-{-# LANGUAGE CPP #-}
-
 {- |
 Module      :  Control.Monad.Error
 Copyright   :  (c) Michael Weber <michael.weber@post.rwth-aachen.de> 2001,
                (c) Jeff Newbern 2003-2006,
                (c) Andriy Palamarchuk 2006
-License     :  BSD-style (see the file libraries/base/LICENSE)
+License     :  BSD-style (see the file LICENSE)
 
 Maintainer  :  libraries@haskell.org
 Stability   :  experimental
@@ -36,10 +29,13 @@
 {-
   Rendered by Michael Weber <mailto:michael.weber@post.rwth-aachen.de>,
   inspired by the Haskell Monad Template Library from
-    Andy Gill (<http://www.cse.ogi.edu/~andy/>)
+    Andy Gill (<http://web.cecs.pdx.edu/~andy/>)
 -}
 module Control.Monad.Error (
-    module Control.Monad.Error.Class,
+    -- * Monads with error handling
+    MonadError(..),
+    Error(..),
+    -- * The ErrorT monad transformer
     ErrorT(..),
     mapErrorT,
     module Control.Monad,
@@ -52,168 +48,14 @@
     -- $ErrorTExample
   ) where
 
-import Control.Monad
-import Control.Monad.Cont.Class
 import Control.Monad.Error.Class
-import Control.Monad.Fix
-import Control.Monad.Reader.Class
-import Control.Monad.State.Class
 import Control.Monad.Trans
-import Control.Monad.Writer.Class
-import Control.Monad.RWS.Class
+import Control.Monad.Trans.Error (ErrorT(..), mapErrorT)
 
+import Control.Monad
+import Control.Monad.Fix
 import Control.Monad.Instances ()
 
--- | Note: this instance does not satisfy the second 'MonadPlus' law
---
--- > v >> mzero   =  mzero
---
-instance MonadPlus IO where
-    mzero       = ioError (userError "mzero")
-    m `mplus` n = m `catch` \_ -> n
-
-instance MonadError IOError IO where
-    throwError = ioError
-    catchError = catch
-
--- ---------------------------------------------------------------------------
--- Our parameterizable error monad
-
-#if !(MIN_VERSION_base(4,2,1))
-
--- These instances are in base-4.3, minus the fail definition and
--- the Error constraint
-
-instance (Error e) => Monad (Either e) where
-    return        = Right
-    Left  l >>= _ = Left l
-    Right r >>= k = k r
-    fail msg      = Left (strMsg msg)
-
-instance (Error e) => MonadFix (Either e) where
-    mfix f = let
-        a = f $ case a of
-            Right r -> r
-            _       -> error "empty mfix argument"
-        in a
-
-#endif /* base to 4.2.0.x */
-
-instance (Error e) => MonadPlus (Either e) where
-    mzero            = Left noMsg
-    Left _ `mplus` n = n
-    m      `mplus` _ = m
-
-instance (Error e) => MonadError e (Either e) where
-    throwError             = Left
-    Left  l `catchError` h = h l
-    Right r `catchError` _ = Right r
-
-{- |
-The error monad transformer. It can be used to add error handling to other
-monads.
-
-The @ErrorT@ Monad structure is parameterized over two things:
-
- * e - The error type.
-
- * m - The inner monad.
-
-Here are some examples of use:
-
-> -- wraps IO action that can throw an error e
-> type ErrorWithIO e a = ErrorT e IO a
-> ==> ErrorT (IO (Either e a))
->
-> -- IO monad wrapped in StateT inside of ErrorT
-> type ErrorAndStateWithIO e s a = ErrorT e (StateT s IO) a
-> ==> ErrorT (StateT s IO (Either e a))
-> ==> ErrorT (StateT (s -> IO (Either e a,s)))
--}
-
-newtype ErrorT e m a = ErrorT { runErrorT :: m (Either e a) }
-
-mapErrorT :: (m (Either e a) -> n (Either e' b))
-          -> ErrorT e m a
-          -> ErrorT e' n b
-mapErrorT f m = ErrorT $ f (runErrorT m)
-
-instance (Monad m) => Functor (ErrorT e m) where
-    fmap f m = ErrorT $ do
-        a <- runErrorT m
-        case a of
-            Left  l -> return (Left  l)
-            Right r -> return (Right (f r))
-
-instance (Monad m, Error e) => Monad (ErrorT e m) where
-    return a = ErrorT $ return (Right a)
-    m >>= k  = ErrorT $ do
-        a <- runErrorT m
-        case a of
-            Left  l -> return (Left l)
-            Right r -> runErrorT (k r)
-    fail msg = ErrorT $ return (Left (strMsg msg))
-
-instance (Monad m, Error e) => MonadPlus (ErrorT e m) where
-    mzero       = ErrorT $ return (Left noMsg)
-    m `mplus` n = ErrorT $ do
-        a <- runErrorT m
-        case a of
-            Left  _ -> runErrorT n
-            Right r -> return (Right r)
-
-instance (MonadFix m, Error e) => MonadFix (ErrorT e m) where
-    mfix f = ErrorT $ mfix $ \a -> runErrorT $ f $ case a of
-        Right r -> r
-        _       -> error "empty mfix argument"
-
-instance (Monad m, Error e) => MonadError e (ErrorT e m) where
-    throwError l     = ErrorT $ return (Left l)
-    m `catchError` h = ErrorT $ do
-        a <- runErrorT m
-        case a of
-            Left  l -> runErrorT (h l)
-            Right r -> return (Right r)
-
--- ---------------------------------------------------------------------------
--- Instances for other mtl transformers
-
-instance (Error e) => MonadTrans (ErrorT e) where
-    lift m = ErrorT $ do
-        a <- m
-        return (Right a)
-
-instance (Error e, MonadIO m) => MonadIO (ErrorT e m) where
-    liftIO = lift . liftIO
-
-instance (Error e, MonadCont m) => MonadCont (ErrorT e m) where
-    callCC f = ErrorT $
-        callCC $ \c ->
-        runErrorT (f (\a -> ErrorT $ c (Right a)))
-
-instance (Error e, MonadRWS r w s m) => MonadRWS r w s (ErrorT e m)
-
-instance (Error e, MonadReader r m) => MonadReader r (ErrorT e m) where
-    ask       = lift ask
-    local f m = ErrorT $ local f (runErrorT m)
-
-instance (Error e, MonadState s m) => MonadState s (ErrorT e m) where
-    get = lift get
-    put = lift . put
-
-instance (Error e, MonadWriter w m) => MonadWriter w (ErrorT e m) where
-    tell     = lift . tell
-    listen m = ErrorT $ do
-        (a, w) <- listen (runErrorT m)
-        case a of
-            Left  l -> return $ Left  l
-            Right r -> return $ Right (r, w)
-    pass   m = ErrorT $ pass $ do
-        a <- runErrorT m
-        case a of
-            Left  l      -> return (Left  l, id)
-            Right (r, f) -> return (Right r, f)
-
 {- $customErrorExample
 Here is an example that demonstrates the use of a custom 'Error' data type with
 the 'throwError' and 'catchError' exception mechanism from 'MonadError'.
@@ -301,4 +143,3 @@
 >reportResult (Right len) = putStrLn ("The length of the string is " ++ (show len))
 >reportResult (Left e) = putStrLn ("Length calculation failed with error: " ++ (show e))
 -}
-
diff --git a/Control/Monad/Error/Class.hs b/Control/Monad/Error/Class.hs
--- a/Control/Monad/Error/Class.hs
+++ b/Control/Monad/Error/Class.hs
@@ -1,12 +1,11 @@
 {-# LANGUAGE UndecidableInstances #-}
--- Needed for the same reasons as in Reader, State etc
 
 {- |
 Module      :  Control.Monad.Error.Class
 Copyright   :  (c) Michael Weber <michael.weber@post.rwth-aachen.de> 2001,
                (c) Jeff Newbern 2003-2006,
                (c) Andriy Palamarchuk 2006
-License     :  BSD-style (see the file libraries/base/LICENSE)
+License     :  BSD-style (see the file LICENSE)
 
 Maintainer  :  libraries@haskell.org
 Stability   :  experimental
@@ -24,7 +23,7 @@
 [Zero and plus:] Zero is represented by an empty error and the plus operation
 executes its second argument if the first fails.
 
-[Example type:] @'Data.Either' String a@
+[Example type:] @'Either' 'String' a@
 
 The Error monad (also called the Exception monad).
 -}
@@ -32,33 +31,31 @@
 {-
   Rendered by Michael Weber <mailto:michael.weber@post.rwth-aachen.de>,
   inspired by the Haskell Monad Template Library from
-    Andy Gill (<http://www.cse.ogi.edu/~andy/>)
+    Andy Gill (<http://web.cecs.pdx.edu/~andy/>)
 -}
 module Control.Monad.Error.Class (
     Error(..),
     MonadError(..),
   ) where
 
--- | An exception to be thrown.
--- An instance must redefine at least one of 'noMsg', 'strMsg'.
-class Error a where
-    -- | Creates an exception without a message.
-    -- Default implementation is @'strMsg' \"\"@.
-    noMsg  :: a
-    -- | Creates an exception with a message.
-    -- Default implementation is 'noMsg'.
-    strMsg :: String -> a
-
-    noMsg    = strMsg ""
-    strMsg _ = noMsg
-
--- | A string can be thrown as an error.
-instance Error String where
-    noMsg  = ""
-    strMsg = id
+import Control.Monad.Trans.Error (Error(..), ErrorT)
+import qualified Control.Monad.Trans.Error as ErrorT (throwError, catchError)
+import Control.Monad.Trans.Identity as Identity
+import Control.Monad.Trans.List as List
+import Control.Monad.Trans.Maybe as Maybe
+import Control.Monad.Trans.Reader as Reader
+import Control.Monad.Trans.RWS.Lazy as LazyRWS
+import Control.Monad.Trans.RWS.Strict as StrictRWS
+import Control.Monad.Trans.State.Lazy as LazyState
+import Control.Monad.Trans.State.Strict as StrictState
+import Control.Monad.Trans.Writer.Lazy as LazyWriter
+import Control.Monad.Trans.Writer.Strict as StrictWriter
 
-instance Error IOError where
-    strMsg = userError
+import Control.Monad.Trans.Class (lift)
+import Control.Exception (IOException)
+import Control.Monad
+import Control.Monad.Instances ()
+import Data.Monoid
 
 {- |
 The strategy of combining computations that can throw exceptions
@@ -72,7 +69,7 @@
 In that case and many other common cases the resulting monad is already defined
 as an instance of the 'MonadError' class.
 You can also define your own error type and\/or use a monad type constructor
-other than @'Data.Either' String@ or @'Data.Either' IOError@.
+other than @'Either' 'String'@ or @'Either' 'IOError'@.
 In these cases you will have to explicitly define instances of the 'Error'
 and\/or 'MonadError' classes.
 -}
@@ -91,3 +88,64 @@
     -}
     catchError :: m a -> (e -> m a) -> m a
 
+instance MonadError IOException IO where
+    throwError = ioError
+    catchError = catch
+
+-- ---------------------------------------------------------------------------
+-- Our parameterizable error monad
+
+instance (Error e) => MonadError e (Either e) where
+    throwError             = Left
+    Left  l `catchError` h = h l
+    Right r `catchError` _ = Right r
+
+instance (Monad m, Error e) => MonadError e (ErrorT e m) where
+    throwError = ErrorT.throwError
+    catchError = ErrorT.catchError
+
+-- ---------------------------------------------------------------------------
+-- Instances for other mtl transformers
+--
+-- All of these instances need UndecidableInstances,
+-- because they do not satisfy the coverage condition.
+
+instance (MonadError e m) => MonadError e (IdentityT m) where
+    throwError = lift . throwError
+    catchError = Identity.liftCatch catchError
+
+instance (MonadError e m) => MonadError e (ListT m) where
+    throwError = lift . throwError
+    catchError = List.liftCatch catchError
+
+instance (MonadError e m) => MonadError e (MaybeT m) where
+    throwError = lift . throwError
+    catchError = Maybe.liftCatch catchError
+
+instance (MonadError e m) => MonadError e (ReaderT r m) where
+    throwError = lift . throwError
+    catchError = Reader.liftCatch catchError
+
+instance (Monoid w, MonadError e m) => MonadError e (LazyRWS.RWST r w s m) where
+    throwError = lift . throwError
+    catchError = LazyRWS.liftCatch catchError
+
+instance (Monoid w, MonadError e m) => MonadError e (StrictRWS.RWST r w s m) where
+    throwError = lift . throwError
+    catchError = StrictRWS.liftCatch catchError
+
+instance (MonadError e m) => MonadError e (LazyState.StateT s m) where
+    throwError = lift . throwError
+    catchError = LazyState.liftCatch catchError
+
+instance (MonadError e m) => MonadError e (StrictState.StateT s m) where
+    throwError = lift . throwError
+    catchError = StrictState.liftCatch catchError
+
+instance (Monoid w, MonadError e m) => MonadError e (LazyWriter.WriterT w m) where
+    throwError = lift . throwError
+    catchError = LazyWriter.liftCatch catchError
+
+instance (Monoid w, MonadError e m) => MonadError e (StrictWriter.WriterT w m) where
+    throwError = lift . throwError
+    catchError = StrictWriter.liftCatch catchError
diff --git a/Control/Monad/Identity.hs b/Control/Monad/Identity.hs
--- a/Control/Monad/Identity.hs
+++ b/Control/Monad/Identity.hs
@@ -4,7 +4,7 @@
                (c) Oregon Graduate Institute of Science and Technology 2001,
                (c) Jeff Newbern 2003-2006,
                (c) Andriy Palamarchuk 2006
-License     :  BSD-style (see the file libraries/base/LICENSE)
+License     :  BSD-style (see the file LICENSE)
 
 Maintainer  :  libraries@haskell.org
 Stability   :  experimental
@@ -30,16 +30,10 @@
 of monad transformers.
 Any monad transformer applied to the @Identity@ monad yields a non-transformer
 version of that monad.
-
-  Inspired by the paper
-  /Functional Programming with Overloading and
-      Higher-Order Polymorphism/,
-    Mark P Jones (<http://web.cecs.pdx.edu/~mpj/>)
-      Advanced School of Functional Programming, 1995.
 -}
 
 module Control.Monad.Identity (
-    Identity(..),
+    module Data.Functor.Identity,
 
     module Control.Monad,
     module Control.Monad.Fix,
@@ -47,49 +41,4 @@
 
 import Control.Monad
 import Control.Monad.Fix
-
-{- | Identity wrapper.
-Abstraction for wrapping up a object.
-If you have an monadic function, say:
-
->   example :: Int -> Identity Int
->   example x = return (x*x)
-
-     you can \"run\" it, using
-
-> Main> runIdentity (example 42)
-> 1764 :: Int
-
-A typical use of the Identity monad is to derive a monad
-from a monad transformer.
-
-@
--- derive the 'Control.Monad.State.State' monad using the 'Control.Monad.State.StateT' monad transformer
-type 'Control.Monad.State.State' s a = 'Control.Monad.State.StateT' s 'Identity' a
-@
-
-The @'runIdentity'@ label is used in the type definition because it follows
-a style of monad definition that explicitly represents monad values as
-computations. In this style, a monadic computation is built up using the monadic
-operators and then the value of the computation is extracted
-using the @run******@ function.
-Because the @Identity@ monad does not do any computation, its definition
-is trivial.
-For a better example of this style of monad,
-see the @'Control.Monad.State.State'@ monad.
--}
-
-newtype Identity a = Identity { runIdentity :: a }
-
--- ---------------------------------------------------------------------------
--- Identity instances for Functor and Monad
-
-instance Functor Identity where
-    fmap f m = Identity (f (runIdentity m))
-
-instance Monad Identity where
-    return a = Identity a
-    m >>= k  = k (runIdentity m)
-
-instance MonadFix Identity where
-    mfix f = Identity (fix (runIdentity . f))
+import Data.Functor.Identity
diff --git a/Control/Monad/List.hs b/Control/Monad/List.hs
--- a/Control/Monad/List.hs
+++ b/Control/Monad/List.hs
@@ -1,16 +1,13 @@
-{-# LANGUAGE UndecidableInstances #-}
--- Needed for the same reasons as in Reader, State etc
-
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Control.Monad.List
 -- Copyright   :  (c) Andy Gill 2001,
 --                (c) Oregon Graduate Institute of Science and Technology, 2001
--- License     :  BSD-style (see the file libraries/base/LICENSE)
+-- License     :  BSD-style (see the file LICENSE)
 --
 -- Maintainer  :  libraries@haskell.org
 -- Stability   :  experimental
--- Portability :  non-portable (multi-parameter type classes)
+-- Portability :  portable
 --
 -- The List monad.
 --
@@ -24,66 +21,5 @@
   ) where
 
 import Control.Monad
-import Control.Monad.Cont.Class
-import Control.Monad.Error.Class
-import Control.Monad.Reader.Class
-import Control.Monad.State.Class
 import Control.Monad.Trans
-
--- ---------------------------------------------------------------------------
--- Our parameterizable list monad, with an inner monad
-
-newtype ListT m a = ListT { runListT :: m [a] }
-
-mapListT :: (m [a] -> n [b]) -> ListT m a -> ListT n b
-mapListT f m = ListT $ f (runListT m)
-
-instance (Monad m) => Functor (ListT m) where
-    fmap f m = ListT $ do
-        a <- runListT m
-        return (map f a)
-
-instance (Monad m) => Monad (ListT m) where
-    return a = ListT $ return [a]
-    m >>= k  = ListT $ do
-        a <- runListT m
-        b <- mapM (runListT . k) a
-        return (concat b)
-    fail _ = ListT $ return []
-
-instance (Monad m) => MonadPlus (ListT m) where
-    mzero       = ListT $ return []
-    m `mplus` n = ListT $ do
-        a <- runListT m
-        b <- runListT n
-        return (a ++ b)
-
--- ---------------------------------------------------------------------------
--- Instances for other mtl transformers
-
-instance MonadTrans ListT where
-    lift m = ListT $ do
-        a <- m
-        return [a]
-
-instance (MonadIO m) => MonadIO (ListT m) where
-    liftIO = lift . liftIO
-
-instance (MonadCont m) => MonadCont (ListT m) where
-    callCC f = ListT $
-        callCC $ \c ->
-        runListT (f (\a -> ListT $ c [a]))
-
-instance (MonadError e m) => MonadError e (ListT m) where
-    throwError       = lift . throwError
-    m `catchError` h = ListT $ runListT m
-        `catchError` \e -> runListT (h e)
-
-instance (MonadReader s m) => MonadReader s (ListT m) where
-    ask       = lift ask
-    local f m = ListT $ local f (runListT m)
-
-instance (MonadState s m) => MonadState s (ListT m) where
-    get = lift get
-    put = lift . put
-
+import Control.Monad.Trans.List
diff --git a/Control/Monad/RWS.hs b/Control/Monad/RWS.hs
--- a/Control/Monad/RWS.hs
+++ b/Control/Monad/RWS.hs
@@ -3,7 +3,7 @@
 -- Module      :  Control.Monad.RWS
 -- Copyright   :  (c) Andy Gill 2001,
 --                (c) Oregon Graduate Institute of Science and Technology, 2001
--- License     :  BSD-style (see the file libraries/base/LICENSE)
+-- License     :  BSD-style (see the file LICENSE)
 --
 -- Maintainer  :  libraries@haskell.org
 -- Stability   :  experimental
@@ -21,6 +21,5 @@
 module Control.Monad.RWS (
     module Control.Monad.RWS.Lazy
   ) where
-
+ 
 import Control.Monad.RWS.Lazy
-
diff --git a/Control/Monad/RWS/Class.hs b/Control/Monad/RWS/Class.hs
--- a/Control/Monad/RWS/Class.hs
+++ b/Control/Monad/RWS/Class.hs
@@ -1,9 +1,12 @@
+{-# LANGUAGE UndecidableInstances #-}
+-- Search for UndecidableInstances to see why this is needed
+
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Control.Monad.RWS.Class
 -- Copyright   :  (c) Andy Gill 2001,
 --                (c) Oregon Graduate Institute of Science and Technology, 2001
--- License     :  BSD-style (see the file libraries/base/LICENSE)
+-- License     :  BSD-style (see the file LICENSE)
 --
 -- Maintainer  :  libraries@haskell.org
 -- Stability   :  experimental
@@ -28,8 +31,27 @@
 import Control.Monad.Reader.Class
 import Control.Monad.State.Class
 import Control.Monad.Writer.Class
+
+import Control.Monad.Trans.Error(Error, ErrorT)
+import Control.Monad.Trans.Maybe(MaybeT)
+import Control.Monad.Trans.Identity(IdentityT)
+import Control.Monad.Trans.RWS.Lazy as Lazy (RWST)
+import qualified Control.Monad.Trans.RWS.Strict as Strict (RWST)
+
 import Data.Monoid
 
 class (Monoid w, MonadReader r m, MonadWriter w m, MonadState s m)
    => MonadRWS r w s m | m -> r, m -> w, m -> s
 
+instance (Monoid w, Monad m) => MonadRWS r w s (Lazy.RWST r w s m)
+instance (Monoid w, Monad m) => MonadRWS r w s (Strict.RWST r w s m)
+ 
+---------------------------------------------------------------------------
+-- Instances for other mtl transformers
+--
+-- All of these instances need UndecidableInstances,
+-- because they do not satisfy the coverage condition.
+ 
+instance (Error e, MonadRWS r w s m) => MonadRWS r w s (ErrorT e m)
+instance (MonadRWS r w s m) => MonadRWS r w s (IdentityT m)
+instance (MonadRWS r w s m) => MonadRWS r w s (MaybeT m)
diff --git a/Control/Monad/RWS/Lazy.hs b/Control/Monad/RWS/Lazy.hs
--- a/Control/Monad/RWS/Lazy.hs
+++ b/Control/Monad/RWS/Lazy.hs
@@ -1,10 +1,9 @@
-{-# LANGUAGE UndecidableInstances #-}
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Control.Monad.RWS.Lazy
 -- Copyright   :  (c) Andy Gill 2001,
 --                (c) Oregon Graduate Institute of Science and Technology, 2001
--- License     :  BSD-style (see the file libraries/base/LICENSE)
+-- License     :  BSD-style (see the file LICENSE)
 --
 -- Maintainer  :  libraries@haskell.org
 -- Stability   :  experimental
@@ -20,16 +19,20 @@
 -----------------------------------------------------------------------------
 
 module Control.Monad.RWS.Lazy (
-    RWS(..),
+    -- * The RWS monad
+    RWS,
+    runRWS,
     evalRWS,
     execRWS,
     mapRWS,
     withRWS,
+    -- * The RWST monad transformer
     RWST(..),
     evalRWST,
     execRWST,
     mapRWST,
     withRWST,
+    -- * Lazy Reader-writer-state monads
     module Control.Monad.RWS.Class,
     module Control.Monad,
     module Control.Monad.Fix,
@@ -37,147 +40,13 @@
     module Data.Monoid,
   ) where
 
-import Control.Monad
-import Control.Monad.Cont.Class
-import Control.Monad.Error.Class
-import Control.Monad.Fix
-import Control.Monad.Reader.Class
-import Control.Monad.State.Class
-import Control.Monad.Trans
-import Control.Monad.Writer.Class
 import Control.Monad.RWS.Class
-import Data.Monoid
 
-newtype RWS r w s a = RWS { runRWS :: r -> s -> (a, s, w) }
-
-evalRWS :: RWS r w s a -> r -> s -> (a, w)
-evalRWS m r s = let
-    (a, _, w) = runRWS m r s
-    in (a, w)
-
-execRWS :: RWS r w s a -> r -> s -> (s, w)
-execRWS m r s = let
-    (_, s', w) = runRWS m r s
-    in (s', w)
-
-mapRWS :: ((a, s, w) -> (b, s, w')) -> RWS r w s a -> RWS r w' s b
-mapRWS f m = RWS $ \r s -> f (runRWS m r s)
-
-withRWS :: (r' -> s -> (r, s)) -> RWS r w s a -> RWS r' w s a
-withRWS f m = RWS $ \r s -> uncurry (runRWS m) (f r s)
-
-instance Functor (RWS r w s) where
-    fmap f m = RWS $ \r s -> let
-        (a, s', w) = runRWS m r s
-        in (f a, s', w)
-
-instance (Monoid w) => Monad (RWS r w s) where
-    return a = RWS $ \_ s -> (a, s, mempty)
-    m >>= k  = RWS $ \r s -> let
-        (a, s',  w)  = runRWS m r s
-        (b, s'', w') = runRWS (k a) r s'
-        in (b, s'', w `mappend` w')
-
-instance (Monoid w) => MonadFix (RWS r w s) where
-    mfix f = RWS $ \r s -> let (a, s', w) = runRWS (f a) r s in (a, s', w)
-
-instance (Monoid w) => MonadReader r (RWS r w s) where
-    ask       = RWS $ \r s -> (r, s, mempty)
-    local f m = RWS $ \r s -> runRWS m (f r) s
-
-instance (Monoid w) => MonadWriter w (RWS r w s) where
-    tell   w = RWS $ \_ s -> ((), s, w)
-    listen m = RWS $ \r s -> let
-        (a, s', w) = runRWS m r s
-        in ((a, w), s', w)
-    pass   m = RWS $ \r s -> let
-        ((a, f), s', w) = runRWS m r s
-        in (a, s', f w)
-
-instance (Monoid w) => MonadState s (RWS r w s) where
-    get   = RWS $ \_ s -> (s, s, mempty)
-    put s = RWS $ \_ _ -> ((), s, mempty)
-
-instance (Monoid w) => MonadRWS r w s (RWS r w s)
-
--- ---------------------------------------------------------------------------
--- Our parameterizable RWS monad, with an inner monad
-
-newtype RWST r w s m a = RWST { runRWST :: r -> s -> m (a, s, w) }
-
-evalRWST :: (Monad m) => RWST r w s m a -> r -> s -> m (a, w)
-evalRWST m r s = do
-    ~(a, _, w) <- runRWST m r s
-    return (a, w)
-
-execRWST :: (Monad m) => RWST r w s m a -> r -> s -> m (s, w)
-execRWST m r s = do
-    ~(_, s', w) <- runRWST m r s
-    return (s', w)
-
-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)
-
-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)
-
-instance (Monad m) => Functor (RWST r w s m) where
-    fmap f m = RWST $ \r s -> do
-        ~(a, s', w) <- runRWST m r s
-        return (f a, s', w)
-
-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
-        ~(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
-
-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
-
-instance (Monoid w, MonadFix m) => MonadFix (RWST r w s m) where
-    mfix f = RWST $ \r s -> mfix $ \ ~(a, _, _) -> runRWST (f a) r s
-
-instance (Monoid w, Monad m) => MonadReader r (RWST r w s m) where
-    ask       = RWST $ \r s -> return (r, s, mempty)
-    local f m = RWST $ \r s -> runRWST m (f r) s
-
-instance (Monoid w, Monad m) => MonadWriter w (RWST r w s m) where
-    tell   w = RWST $ \_ s -> return ((),s,w)
-    listen m = RWST $ \r s -> do
-        ~(a, s', w) <- runRWST m r s
-        return ((a, w), s', w)
-    pass   m = RWST $ \r s -> do
-        ~((a, f), s', w) <- runRWST m r s
-        return (a, s', f w)
-
-instance (Monoid w, Monad m) => MonadState s (RWST r w s m) where
-    get   = RWST $ \_ s -> return (s, s, mempty)
-    put s = RWST $ \_ _ -> return ((), s, mempty)
-
-instance (Monoid w, Monad m) => MonadRWS r w s (RWST r w s m)
-
--- ---------------------------------------------------------------------------
--- Instances for other mtl transformers
-
-instance (Monoid w) => MonadTrans (RWST r w s) where
-    lift m = RWST $ \_ s -> do
-        a <- m
-        return (a, s, mempty)
-
-instance (Monoid w, MonadIO m) => MonadIO (RWST r w s m) where
-    liftIO = lift . liftIO
-
-instance (Monoid w, MonadCont m) => MonadCont (RWST r w s m) where
-    callCC f = RWST $ \r s ->
-        callCC $ \c ->
-        runRWST (f (\a -> RWST $ \_ s' -> c (a, s', mempty))) r s
-
-instance (Monoid w, MonadError e m) => MonadError e (RWST r w s m) where
-    throwError       = lift . throwError
-    m `catchError` h = RWST $ \r s -> runRWST m r s
-        `catchError` \e -> runRWST (h e) r s
+import Control.Monad.Trans
+import Control.Monad.Trans.RWS.Lazy (
+    RWS, runRWS, evalRWS, execRWS, mapRWS, withRWS,
+    RWST(..), evalRWST, execRWST, mapRWST, withRWST)
 
+import Control.Monad
+import Control.Monad.Fix
+import Data.Monoid
diff --git a/Control/Monad/RWS/Strict.hs b/Control/Monad/RWS/Strict.hs
--- a/Control/Monad/RWS/Strict.hs
+++ b/Control/Monad/RWS/Strict.hs
@@ -1,16 +1,15 @@
-{-# LANGUAGE UndecidableInstances #-}
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Control.Monad.RWS.Strict
 -- Copyright   :  (c) Andy Gill 2001,
 --                (c) Oregon Graduate Institute of Science and Technology, 2001
--- License     :  BSD-style (see the file libraries/base/LICENSE)
+-- License     :  BSD-style (see the file LICENSE)
 --
 -- Maintainer  :  libraries@haskell.org
 -- Stability   :  experimental
 -- Portability :  non-portable (multi-param classes, functional dependencies)
 --
--- Strict RWS Monad.
+-- Strict RWS monad.
 --
 --      Inspired by the paper
 --      /Functional Programming with Overloading and
@@ -20,16 +19,20 @@
 -----------------------------------------------------------------------------
 
 module Control.Monad.RWS.Strict (
-    RWS(..),
+    -- * The RWS monad
+    RWS,
+    runRWS,
     evalRWS,
     execRWS,
     mapRWS,
     withRWS,
+    -- * The RWST monad transformer
     RWST(..),
     evalRWST,
     execRWST,
     mapRWST,
     withRWST,
+    -- * Strict Reader-writer-state monads
     module Control.Monad.RWS.Class,
     module Control.Monad,
     module Control.Monad.Fix,
@@ -37,143 +40,13 @@
     module Data.Monoid,
   ) where
 
-import Control.Monad
-import Control.Monad.Cont.Class
-import Control.Monad.Error.Class
-import Control.Monad.Fix
-import Control.Monad.Reader.Class
-import Control.Monad.State.Class
-import Control.Monad.Trans
-import Control.Monad.Writer.Class
 import Control.Monad.RWS.Class
-import Data.Monoid
 
-newtype RWS r w s a = RWS { runRWS :: r -> s -> (a, s, w) }
-
-evalRWS :: RWS r w s a -> r -> s -> (a, w)
-evalRWS m r s = case runRWS m r s of
-                    (a, _, w) -> (a, w)
-
-execRWS :: RWS r w s a -> r -> s -> (s, w)
-execRWS m r s = case runRWS m r s of
-                    (_, s', w) -> (s', w)
-
-mapRWS :: ((a, s, w) -> (b, s, w')) -> RWS r w s a -> RWS r w' s b
-mapRWS f m = RWS $ \r s -> f (runRWS m r s)
-
-withRWS :: (r' -> s -> (r, s)) -> RWS r w s a -> RWS r' w s a
-withRWS f m = RWS $ \r s -> uncurry (runRWS m) (f r s)
-
-instance Functor (RWS r w s) where
-    fmap f m = RWS $ \r s -> case runRWS m r s of
-                                 (a, s', w) -> (f a, s', w)
-
-instance (Monoid w) => Monad (RWS r w s) where
-    return a = RWS $ \_ s -> (a, s, mempty)
-    m >>= k  = RWS $ \r s -> case runRWS m r s of
-                                 (a, s',  w) ->
-                                     case runRWS (k a) r s' of
-                                         (b, s'', w') ->
-                                             (b, s'', w `mappend` w')
-
-instance (Monoid w) => MonadFix (RWS r w s) where
-    mfix f = RWS $ \r s -> let (a, s', w) = runRWS (f a) r s in (a, s', w)
-
-instance (Monoid w) => MonadReader r (RWS r w s) where
-    ask       = RWS $ \r s -> (r, s, mempty)
-    local f m = RWS $ \r s -> runRWS m (f r) s
-
-instance (Monoid w) => MonadWriter w (RWS r w s) where
-    tell   w = RWS $ \_ s -> ((), s, w)
-    listen m = RWS $ \r s -> case runRWS m r s of
-                                 (a, s', w) -> ((a, w), s', w)
-    pass   m = RWS $ \r s -> case runRWS m r s of
-                                 ((a, f), s', w) -> (a, s', f w)
-
-instance (Monoid w) => MonadState s (RWS r w s) where
-    get   = RWS $ \_ s -> (s, s, mempty)
-    put s = RWS $ \_ _ -> ((), s, mempty)
-
-instance (Monoid w) => MonadRWS r w s (RWS r w s)
-
--- ---------------------------------------------------------------------------
--- Our parameterizable RWS monad, with an inner monad
-
-newtype RWST r w s m a = RWST { runRWST :: r -> s -> m (a, s, w) }
-
-evalRWST :: (Monad m) => RWST r w s m a -> r -> s -> m (a, w)
-evalRWST m r s = do
-    (a, _, w) <- runRWST m r s
-    return (a, w)
-
-execRWST :: (Monad m) => RWST r w s m a -> r -> s -> m (s, w)
-execRWST m r s = do
-    (_, s', w) <- runRWST m r s
-    return (s', w)
-
-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)
-
-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)
-
-instance (Monad m) => Functor (RWST r w s m) where
-    fmap f m = RWST $ \r s -> do
-        (a, s', w) <- runRWST m r s
-        return (f a, s', w)
-
-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
-        (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
-
-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
-
-instance (Monoid w, MonadFix m) => MonadFix (RWST r w s m) where
-    mfix f = RWST $ \r s -> mfix $ \ ~(a, _, _) -> runRWST (f a) r s
-
-instance (Monoid w, Monad m) => MonadReader r (RWST r w s m) where
-    ask       = RWST $ \r s -> return (r, s, mempty)
-    local f m = RWST $ \r s -> runRWST m (f r) s
-
-instance (Monoid w, Monad m) => MonadWriter w (RWST r w s m) where
-    tell   w = RWST $ \_ s -> return ((),s,w)
-    listen m = RWST $ \r s -> do
-        (a, s', w) <- runRWST m r s
-        return ((a, w), s', w)
-    pass   m = RWST $ \r s -> do
-        ((a, f), s', w) <- runRWST m r s
-        return (a, s', f w)
-
-instance (Monoid w, Monad m) => MonadState s (RWST r w s m) where
-    get   = RWST $ \_ s -> return (s, s, mempty)
-    put s = RWST $ \_ _ -> return ((), s, mempty)
-
-instance (Monoid w, Monad m) => MonadRWS r w s (RWST r w s m)
-
--- ---------------------------------------------------------------------------
--- Instances for other mtl transformers
-
-instance (Monoid w) => MonadTrans (RWST r w s) where
-    lift m = RWST $ \_ s -> do
-        a <- m
-        return (a, s, mempty)
-
-instance (Monoid w, MonadIO m) => MonadIO (RWST r w s m) where
-    liftIO = lift . liftIO
-
-instance (Monoid w, MonadCont m) => MonadCont (RWST r w s m) where
-    callCC f = RWST $ \r s ->
-        callCC $ \c ->
-        runRWST (f (\a -> RWST $ \_ s' -> c (a, s', mempty))) r s
-
-instance (Monoid w, MonadError e m) => MonadError e (RWST r w s m) where
-    throwError       = lift . throwError
-    m `catchError` h = RWST $ \r s -> runRWST m r s
-        `catchError` \e -> runRWST (h e) r s
+import Control.Monad.Trans
+import Control.Monad.Trans.RWS.Strict (
+    RWS, runRWS, evalRWS, execRWS, mapRWS, withRWS,
+    RWST(..), evalRWST, execRWST, mapRWST, withRWST)
 
+import Control.Monad
+import Control.Monad.Fix
+import Data.Monoid
diff --git a/Control/Monad/Reader.hs b/Control/Monad/Reader.hs
--- a/Control/Monad/Reader.hs
+++ b/Control/Monad/Reader.hs
@@ -1,11 +1,10 @@
-{-# LANGUAGE UndecidableInstances #-}
 {- |
 Module      :  Control.Monad.Reader
 Copyright   :  (c) Andy Gill 2001,
                (c) Oregon Graduate Institute of Science and Technology 2001,
                (c) Jeff Newbern 2003-2007,
                (c) Andriy Palamarchuk 2007
-License     :  BSD-style (see the file libraries/base/LICENSE)
+License     :  BSD-style (see the file LICENSE)
 
 Maintainer  :  libraries@haskell.org
 Stability   :  experimental
@@ -38,10 +37,15 @@
 -}
 
 module Control.Monad.Reader (
-    module Control.Monad.Reader.Class,
-    Reader(..),
+    -- * MonadReader class
+    MonadReader(..),
+    asks,
+    -- * The Reader monad
+    Reader,
+    runReader,
     mapReader,
     withReader,
+    -- * The ReaderT monad transformer
     ReaderT(..),
     mapReaderT,
     withReaderT,
@@ -58,131 +62,20 @@
     -- $ReaderTExample
     ) where
 
-import Control.Monad
-import Control.Monad.Cont.Class
-import Control.Monad.Error.Class
-import Control.Monad.Fix
-import Control.Monad.Instances ()
 import Control.Monad.Reader.Class
-import Control.Monad.State.Class
-import Control.Monad.Trans
-import Control.Monad.Writer.Class
 
-{- |
-The parameterizable reader monad.
-
-The @return@ function creates a @Reader@ that ignores the environment,
-and produces the given value.
-
-The binding operator @>>=@ produces a @Reader@ that uses the environment
-to extract the value its left-hand side,
-and then applies the bound function to that value in the same environment.
--}
-newtype Reader r a = Reader {
-    {- |
-    Runs @Reader@ and extracts the final value from it.
-    To extract the value apply @(runReader reader)@ to an environment value.  
-    Parameters:
-
-    * A @Reader@ to run.
-
-    * An initial environment.
-    -}
-    runReader :: r -> a
-}
-
-mapReader :: (a -> b) -> Reader r a -> Reader r b
-mapReader f m = Reader $ f . runReader m
-
--- | A more general version of 'local'.
-
-withReader :: (r' -> r) -> Reader r a -> Reader r' a
-withReader f m = Reader $ runReader m . f
-
-instance Functor (Reader r) where
-    fmap f m = Reader $ \r -> f (runReader m r)
-
-instance Monad (Reader r) where
-    return a = Reader $ \_ -> a
-    m >>= k  = Reader $ \r -> runReader (k (runReader m r)) r
-
-instance MonadFix (Reader r) where
-    mfix f = Reader $ \r -> let a = runReader (f a) r in a
-
-instance MonadReader r (Reader r) where
-    ask       = Reader id
-    local f m = Reader $ runReader m . f
-
-{- |
-The reader monad transformer.
-Can be used to add environment reading functionality to other monads.
--}
-newtype ReaderT r m a = ReaderT { runReaderT :: r -> m a }
-
-mapReaderT :: (m a -> n b) -> ReaderT w m a -> ReaderT w n b
-mapReaderT f m = ReaderT $ f . runReaderT m
-
-withReaderT :: (r' -> r) -> ReaderT r m a -> ReaderT r' m a
-withReaderT f m = ReaderT $ runReaderT m . f
-
-instance (Monad m) => Functor (ReaderT r m) where
-    fmap f m = ReaderT $ \r -> do
-        a <- runReaderT m r
-        return (f a)
-
-instance (Monad m) => Monad (ReaderT r m) where
-    return a = ReaderT $ \_ -> return a
-    m >>= k  = ReaderT $ \r -> do
-        a <- runReaderT m r
-        runReaderT (k a) r
-    fail msg = ReaderT $ \_ -> fail msg
-
-instance (MonadPlus m) => MonadPlus (ReaderT r m) where
-    mzero       = ReaderT $ \_ -> mzero
-    m `mplus` n = ReaderT $ \r -> runReaderT m r `mplus` runReaderT n r
-
-instance (MonadFix m) => MonadFix (ReaderT r m) where
-    mfix f = ReaderT $ \r -> mfix $ \a -> runReaderT (f a) r
-
-instance (Monad m) => MonadReader r (ReaderT r m) where
-    ask       = ReaderT return
-    local f m = ReaderT $ \r -> runReaderT m (f r)
-
--- ---------------------------------------------------------------------------
--- Instances for other mtl transformers
-
-instance MonadTrans (ReaderT r) where
-    lift m = ReaderT $ \_ -> m
-
-instance (MonadIO m) => MonadIO (ReaderT r m) where
-    liftIO = lift . liftIO
-
-instance (MonadCont m) => MonadCont (ReaderT r m) where
-    callCC f = ReaderT $ \r ->
-        callCC $ \c ->
-        runReaderT (f (\a -> ReaderT $ \_ -> c a)) r
-
-instance (MonadError e m) => MonadError e (ReaderT r m) where
-    throwError       = lift . throwError
-    m `catchError` h = ReaderT $ \r -> runReaderT m r
-        `catchError` \e -> runReaderT (h e) r
-
--- Needs UndecidableInstances
-instance (MonadState s m) => MonadState s (ReaderT r m) where
-    get = lift get
-    put = lift . put
+import Control.Monad.Trans.Reader (
+    Reader, runReader, mapReader, withReader,
+    ReaderT(..), mapReaderT, withReaderT)
+import Control.Monad.Trans
 
--- This instance needs UndecidableInstances, because
--- it does not satisfy the coverage condition
-instance (MonadWriter w m) => MonadWriter w (ReaderT r m) where
-    tell     = lift . tell
-    listen m = ReaderT $ \w -> listen (runReaderT m w)
-    pass   m = ReaderT $ \w -> pass   (runReaderT m w)
+import Control.Monad
+import Control.Monad.Fix
 
 {- $simpleReaderExample
 
 In this example the @Reader@ monad provides access to variable bindings.
-Bindings are a 'Map' of integer variables.
+Bindings are a @Map@ of integer variables.
 The variable @count@ contains number of variables in the bindings.
 You can see how to run a Reader monad and retrieve data from it
 with 'runReader', how to access the Reader data with 'ask' and 'asks'.
diff --git a/Control/Monad/Reader/Class.hs b/Control/Monad/Reader/Class.hs
--- a/Control/Monad/Reader/Class.hs
+++ b/Control/Monad/Reader/Class.hs
@@ -1,11 +1,12 @@
 {-# LANGUAGE UndecidableInstances #-}
+-- Search for UndecidableInstances to see why this is needed
 {- |
 Module      :  Control.Monad.Reader.Class
 Copyright   :  (c) Andy Gill 2001,
                (c) Oregon Graduate Institute of Science and Technology 2001,
                (c) Jeff Newbern 2003-2007,
                (c) Andriy Palamarchuk 2007
-License     :  BSD-style (see the file libraries/base/LICENSE)
+License     :  BSD-style (see the file LICENSE)
 
 Maintainer  :  libraries@haskell.org
 Stability   :  experimental
@@ -42,25 +43,47 @@
     asks,
     ) where
 
-import Control.Monad.Instances ()
+import Control.Monad.Trans.Cont as Cont
+import Control.Monad.Trans.Error
+import Control.Monad.Trans.Identity
+import Control.Monad.Trans.List
+import Control.Monad.Trans.Maybe
+import Control.Monad.Trans.Reader (ReaderT)
+import qualified Control.Monad.Trans.Reader as ReaderT (ask, local)
+import qualified Control.Monad.Trans.RWS.Lazy as LazyRWS (RWST, ask, local)
+import qualified Control.Monad.Trans.RWS.Strict as StrictRWS (RWST, ask, local)
+import Control.Monad.Trans.State.Lazy as Lazy
+import Control.Monad.Trans.State.Strict as Strict
+import Control.Monad.Trans.Writer.Lazy as Lazy
+import Control.Monad.Trans.Writer.Strict as Strict
 
-{- |
-See examples in "Control.Monad.Reader".
-Note, the partially applied function type @(->) r@ is a simple reader monad.
-See the @instance@ declaration below.
--}
+import Control.Monad.Trans.Class (lift)
+import Control.Monad
+import Data.Monoid
+
+-- ----------------------------------------------------------------------------
+-- class MonadReader
+--  asks for the internal (non-mutable) state.
+
+-- | See examples in "Control.Monad.Reader".
+-- Note, the partially applied function type @(->) r@ is a simple reader monad.
+-- See the @instance@ declaration below.
 class (Monad m) => MonadReader r m | m -> r where
     -- | Retrieves the monad environment.
     ask   :: m r
-    {- | Executes a computation in a modified environment. Parameters:
 
-    * The function to modify the environment.
-
-    * @Reader@ to run.
+    -- | Executes a computation in a modified environment.
+    local :: (r -> r)	-- ^ The function to modify the environment.
+          -> m a	-- ^ @Reader@ to run in the modified environment.
+          -> m a
 
-    * The resulting @Reader@.
-    -}
-    local :: (r -> r) -> m a -> m a
+-- | Retrieves a function of the current environment.
+asks :: (MonadReader r m)
+    => (r -> a)		-- ^ The selector function to apply to the environment.
+    -> m a
+asks f = do
+    r <- ask
+    return (f r)
 
 -- ----------------------------------------------------------------------------
 -- The partially applied function type is a simple reader monad
@@ -69,15 +92,56 @@
     ask       = id
     local f m = m . f
 
-{- |
-Retrieves a function of the current environment. Parameters:
+instance (Monad m) => MonadReader r (ReaderT r m) where
+    ask = ReaderT.ask
+    local = ReaderT.local
 
-* The selector function to apply to the environment.
+instance (Monad m, Monoid w) => MonadReader r (LazyRWS.RWST r w s m) where
+    ask = LazyRWS.ask
+    local = LazyRWS.local
 
-See an example in "Control.Monad.Reader".
--}
-asks :: (MonadReader r m) => (r -> a) -> m a
-asks f = do
-    r <- ask
-    return (f r)
+instance (Monad m, Monoid w) => MonadReader r (StrictRWS.RWST r w s m) where
+    ask = StrictRWS.ask
+    local = StrictRWS.local
 
+-- ---------------------------------------------------------------------------
+-- Instances for other mtl transformers
+--
+-- All of these instances need UndecidableInstances,
+-- because they do not satisfy the coverage condition.
+
+instance (MonadReader r' m) => MonadReader r' (ContT r m) where
+    ask   = lift ask
+    local = Cont.liftLocal ask local
+
+instance (Error e, MonadReader r m) => MonadReader r (ErrorT e m) where
+    ask   = lift ask
+    local = mapErrorT . local
+
+instance (MonadReader r m) => MonadReader r (IdentityT m) where
+    ask   = lift ask
+    local = mapIdentityT . local
+
+instance (MonadReader r m) => MonadReader r (ListT m) where
+    ask   = lift ask
+    local = mapListT . local
+
+instance (MonadReader r m) => MonadReader r (MaybeT m) where
+    ask   = lift ask
+    local = mapMaybeT . local
+
+instance (MonadReader r m) => MonadReader r (Lazy.StateT s m) where
+    ask   = lift ask
+    local = Lazy.mapStateT . local
+
+instance (MonadReader r m) => MonadReader r (Strict.StateT s m) where
+    ask   = lift ask
+    local = Strict.mapStateT . local
+
+instance (Monoid w, MonadReader r m) => MonadReader r (Lazy.WriterT w m) where
+    ask   = lift ask
+    local = Lazy.mapWriterT . local
+
+instance (Monoid w, MonadReader r m) => MonadReader r (Strict.WriterT w m) where
+    ask   = lift ask
+    local = Strict.mapWriterT . local
diff --git a/Control/Monad/State.hs b/Control/Monad/State.hs
--- a/Control/Monad/State.hs
+++ b/Control/Monad/State.hs
@@ -3,7 +3,7 @@
 -- Module      :  Control.Monad.State
 -- Copyright   :  (c) Andy Gill 2001,
 --                (c) Oregon Graduate Institute of Science and Technology, 2001
--- License     :  BSD-style (see the file libraries/base/LICENSE)
+-- License     :  BSD-style (see the file LICENSE)
 --
 -- Maintainer  :  libraries@haskell.org
 -- Stability   :  experimental
@@ -24,4 +24,3 @@
   ) where
 
 import Control.Monad.State.Lazy
-
diff --git a/Control/Monad/State/Class.hs b/Control/Monad/State/Class.hs
--- a/Control/Monad/State/Class.hs
+++ b/Control/Monad/State/Class.hs
@@ -1,9 +1,12 @@
+{-# LANGUAGE UndecidableInstances #-}
+-- Search for UndecidableInstances to see why this is needed
+
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Control.Monad.State.Class
 -- Copyright   :  (c) Andy Gill 2001,
 --                (c) Oregon Graduate Institute of Science and Technology, 2001
--- License     :  BSD-style (see the file libraries/base/LICENSE)
+-- License     :  BSD-style (see the file LICENSE)
 --
 -- Maintainer  :  libraries@haskell.org
 -- Stability   :  experimental
@@ -20,19 +23,34 @@
 -----------------------------------------------------------------------------
 
 module Control.Monad.State.Class (
-    -- * MonadState class
     MonadState(..),
     modify,
     gets,
   ) where
 
+import Control.Monad.Trans.Cont
+import Control.Monad.Trans.Error
+import Control.Monad.Trans.Identity
+import Control.Monad.Trans.List
+import Control.Monad.Trans.Maybe
+import Control.Monad.Trans.Reader
+import qualified Control.Monad.Trans.RWS.Lazy as LazyRWS (RWST, get, put)
+import qualified Control.Monad.Trans.RWS.Strict as StrictRWS (RWST, get, put)
+import qualified Control.Monad.Trans.State.Lazy as Lazy (StateT, get, put)
+import qualified Control.Monad.Trans.State.Strict as Strict (StateT, get, put)
+import Control.Monad.Trans.Writer.Lazy as Lazy
+import Control.Monad.Trans.Writer.Strict as Strict
+
+import Control.Monad.Trans.Class (lift)
+import Control.Monad
+import Data.Monoid
+
 -- ---------------------------------------------------------------------------
--- | /get/ returns the state from the internals of the monad.
---
--- /put/ replaces the state inside the monad.
 
 class (Monad m) => MonadState s m | m -> s where
+    -- | Return the state from the internals of the monad.
     get :: m s
+    -- | Replace the state inside the monad.
     put :: s -> m ()
 
 -- | Monadic state transformer.
@@ -60,3 +78,56 @@
     s <- get
     return (f s)
 
+instance (Monad m) => MonadState s (Lazy.StateT s m) where
+    get = Lazy.get
+    put = Lazy.put
+
+instance (Monad m) => MonadState s (Strict.StateT s m) where
+    get = Strict.get
+    put = Strict.put
+
+instance (Monad m, Monoid w) => MonadState s (LazyRWS.RWST r w s m) where
+    get = LazyRWS.get
+    put = LazyRWS.put
+
+instance (Monad m, Monoid w) => MonadState s (StrictRWS.RWST r w s m) where
+    get = StrictRWS.get
+    put = StrictRWS.put
+
+-- ---------------------------------------------------------------------------
+-- Instances for other mtl transformers
+--
+-- All of these instances need UndecidableInstances,
+-- because they do not satisfy the coverage condition.
+
+instance (MonadState s m) => MonadState s (ContT r m) where
+    get = lift get
+    put = lift . put
+
+instance (Error e, MonadState s m) => MonadState s (ErrorT e m) where
+    get = lift get
+    put = lift . put
+
+instance (MonadState s m) => MonadState s (IdentityT m) where
+    get = lift get
+    put = lift . put
+
+instance (MonadState s m) => MonadState s (ListT m) where
+    get = lift get
+    put = lift . put
+
+instance (MonadState s m) => MonadState s (MaybeT m) where
+    get = lift get
+    put = lift . put
+
+instance (MonadState s m) => MonadState s (ReaderT r m) where
+    get = lift get
+    put = lift . put
+
+instance (Monoid w, MonadState s m) => MonadState s (Lazy.WriterT w m) where
+    get = lift get
+    put = lift . put
+
+instance (Monoid w, MonadState s m) => MonadState s (Strict.WriterT w m) where
+    get = lift get
+    put = lift . put
diff --git a/Control/Monad/State/Lazy.hs b/Control/Monad/State/Lazy.hs
--- a/Control/Monad/State/Lazy.hs
+++ b/Control/Monad/State/Lazy.hs
@@ -1,12 +1,9 @@
-{-# LANGUAGE UndecidableInstances #-}
--- Search for UndecidableInstances to see why this is needed
-
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Control.Monad.State.Lazy
 -- Copyright   :  (c) Andy Gill 2001,
 --                (c) Oregon Graduate Institute of Science and Technology, 2001
--- License     :  BSD-style (see the file libraries/base/LICENSE)
+-- License     :  BSD-style (see the file LICENSE)
 --
 -- Maintainer  :  libraries@haskell.org
 -- Stability   :  experimental
@@ -19,20 +16,22 @@
 --          Higher-Order Polymorphism/,
 --        Mark P Jones (<http://web.cecs.pdx.edu/~mpj/>)
 --          Advanced School of Functional Programming, 1995.
---
--- See below for examples.
 
 -----------------------------------------------------------------------------
 
 module Control.Monad.State.Lazy (
-    module Control.Monad.State.Class,
-    -- * The State Monad
-    State(..),
+    -- * MonadState class
+    MonadState(..),
+    modify,
+    gets,
+    -- * The State monad
+    State,
+    runState,
     evalState,
     execState,
     mapState,
     withState,
-    -- * The StateT Monad
+    -- * The StateT monad transformer
     StateT(..),
     evalStateT,
     execStateT,
@@ -45,185 +44,15 @@
     -- $examples
   ) where
 
-import Control.Monad
-import Control.Monad.Cont.Class
-import Control.Monad.Error.Class
-import Control.Monad.Fix
-import Control.Monad.Reader.Class
 import Control.Monad.State.Class
-import Control.Monad.Trans
-import Control.Monad.Writer.Class
 
--- ---------------------------------------------------------------------------
--- | A parameterizable state monad where /s/ is the type of the state
--- to carry and /a/ is the type of the /return value/.
-
-newtype State s a = State { runState :: s -> (a, s) }
-
--- |Evaluate this state monad with the given initial state,throwing
--- away the final state.  Very much like @fst@ composed with
--- @runstate@.
-
-evalState :: State s a -- ^The state to evaluate
-          -> s         -- ^An initial value
-          -> a         -- ^The return value of the state application
-evalState m s = fst (runState m s)
-
--- |Execute this state and return the new state, throwing away the
--- return value.  Very much like @snd@ composed with
--- @runstate@.
-
-execState :: State s a -- ^The state to evaluate
-          -> s         -- ^An initial value
-          -> s         -- ^The new state
-execState m s = snd (runState m s)
-
--- |Map a stateful computation from one (return value, state) pair to
--- another.  For instance, to convert numberTree from a function that
--- returns a tree to a function that returns the sum of the numbered
--- tree (see the Examples section for numberTree and sumTree) you may
--- write:
---
--- > sumNumberedTree :: (Eq a) => Tree a -> State (Table a) Int
--- > sumNumberedTree = mapState (\ (t, tab) -> (sumTree t, tab))  . numberTree
-
-mapState :: ((a, s) -> (b, s)) -> State s a -> State s b
-mapState f m = State $ f . runState m
-
--- |Apply this function to this state and return the resulting state.
-withState :: (s -> s) -> State s a -> State s a
-withState f m = State $ runState m . f
-
-instance Functor (State s) where
-    fmap f m = State $ \s -> let
-        (a, s') = runState m s
-        in (f a, s')
-
-instance Monad (State s) where
-    return a = State $ \s -> (a, s)
-    m >>= k  = State $ \s -> let
-        (a, s') = runState m s
-        in runState (k a) s'
-
-instance MonadFix (State s) where
-    mfix f = State $ \s -> let (a, s') = runState (f a) s in (a, s')
-
-instance MonadState s (State s) where
-    get   = State $ \s -> (s, s)
-    put s = State $ \_ -> ((), s)
-
--- ---------------------------------------------------------------------------
--- | A parameterizable state monad for encapsulating an inner
--- monad.
---
--- The StateT Monad structure is parameterized over two things:
---
---   * s - The state.
---
---   * m - The inner monad.
---
--- Here are some examples of use:
---
--- (Parser from ParseLib with Hugs)
---
--- >  type Parser a = StateT String [] a
--- >     ==> StateT (String -> [(a,String)])
---
--- For example, item can be written as:
---
--- >   item = do (x:xs) <- get
--- >          put xs
--- >          return x
--- >
--- >   type BoringState s a = StateT s Indentity a
--- >        ==> StateT (s -> Identity (a,s))
--- >
--- >   type StateWithIO s a = StateT s IO a
--- >        ==> StateT (s -> IO (a,s))
--- >
--- >   type StateWithErr s a = StateT s Maybe a
--- >        ==> StateT (s -> Maybe (a,s))
-
-newtype StateT s m a = StateT { runStateT :: s -> m (a,s) }
-
--- |Similar to 'evalState'
-evalStateT :: (Monad m) => StateT s m a -> s -> m a
-evalStateT m s = do
-    ~(a, _) <- runStateT m s
-    return a
-
--- |Similar to 'execState'
-execStateT :: (Monad m) => StateT s m a -> s -> m s
-execStateT m s = do
-    ~(_, s') <- runStateT m s
-    return s'
-
--- |Similar to 'mapState'
-mapStateT :: (m (a, s) -> n (b, s)) -> StateT s m a -> StateT s n b
-mapStateT f m = StateT $ f . runStateT m
-
--- |Similar to 'withState'
-withStateT :: (s -> s) -> StateT s m a -> StateT s m a
-withStateT f m = StateT $ runStateT m . f
-
-instance (Monad m) => Functor (StateT s m) where
-    fmap f m = StateT $ \s -> do
-        ~(x, s') <- runStateT m s
-        return (f x, s')
-
-instance (Monad m) => Monad (StateT s m) where
-    return a = StateT $ \s -> return (a, s)
-    m >>= k  = StateT $ \s -> do
-        ~(a, s') <- runStateT m s
-        runStateT (k a) s'
-    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
-
-instance (MonadFix m) => MonadFix (StateT s m) where
-    mfix f = StateT $ \s -> mfix $ \ ~(a, _) -> runStateT (f a) s
-
-instance (Monad m) => MonadState s (StateT s m) where
-    get   = StateT $ \s -> return (s, s)
-    put s = StateT $ \_ -> return ((), s)
-
--- ---------------------------------------------------------------------------
--- Instances for other mtl transformers
-
-instance MonadTrans (StateT s) where
-    lift m = StateT $ \s -> do
-        a <- m
-        return (a, s)
-
-instance (MonadIO m) => MonadIO (StateT s m) where
-    liftIO = lift . liftIO
-
-instance (MonadCont m) => MonadCont (StateT s m) where
-    callCC f = StateT $ \s ->
-        callCC $ \c ->
-        runStateT (f (\a -> StateT $ \s' -> c (a, s'))) s
-
-instance (MonadError e m) => MonadError e (StateT s m) where
-    throwError       = lift . throwError
-    m `catchError` h = StateT $ \s -> runStateT m s
-        `catchError` \e -> runStateT (h e) s
-
--- Needs UndecidableInstances
-instance (MonadReader r m) => MonadReader r (StateT s m) where
-    ask       = lift ask
-    local f m = StateT $ \s -> local f (runStateT m s)
+import Control.Monad.Trans
+import Control.Monad.Trans.State.Lazy
+        (State, runState, evalState, execState, mapState, withState,
+         StateT(..), evalStateT, execStateT, mapStateT, withStateT)
 
--- Needs UndecidableInstances
-instance (MonadWriter w m) => MonadWriter w (StateT s m) where
-    tell     = lift . tell
-    listen m = StateT $ \s -> do
-        ~((a, s'), w) <- listen (runStateT m s)
-        return ((a, w), s')
-    pass   m = StateT $ \s -> pass $ do
-        ~((a, f), s') <- runStateT m s
-        return ((a, s'), f)
+import Control.Monad
+import Control.Monad.Fix
 
 -- ---------------------------------------------------------------------------
 -- $examples
diff --git a/Control/Monad/State/Strict.hs b/Control/Monad/State/Strict.hs
--- a/Control/Monad/State/Strict.hs
+++ b/Control/Monad/State/Strict.hs
@@ -1,12 +1,9 @@
-{-# LANGUAGE UndecidableInstances #-}
--- Search for UndecidableInstances to see why this is needed
-
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Control.Monad.State.Strict
 -- Copyright   :  (c) Andy Gill 2001,
---           (c) Oregon Graduate Institute of Science and Technology, 2001
--- License     :  BSD-style (see the file libraries/base/LICENSE)
+--                (c) Oregon Graduate Institute of Science and Technology, 2001
+-- License     :  BSD-style (see the file LICENSE)
 --
 -- Maintainer  :  libraries@haskell.org
 -- Stability   :  experimental
@@ -19,20 +16,22 @@
 --          Higher-Order Polymorphism/,
 --        Mark P Jones (<http://web.cecs.pdx.edu/~mpj/>)
 --          Advanced School of Functional Programming, 1995.
---
--- See below for examples.
 
 -----------------------------------------------------------------------------
 
 module Control.Monad.State.Strict (
-    module Control.Monad.State.Class,
-    -- * The State Monad
-    State(..),
+    -- * MonadState class
+    MonadState(..),
+    modify,
+    gets,
+    -- * The State monad
+    State,
+    runState,
     evalState,
     execState,
     mapState,
     withState,
-    -- * The StateT Monad
+    -- * The StateT monad transformer
     StateT(..),
     evalStateT,
     execStateT,
@@ -45,184 +44,15 @@
     -- $examples
   ) where
 
-import Control.Monad
-import Control.Monad.Cont.Class
-import Control.Monad.Error.Class
-import Control.Monad.Fix
-import Control.Monad.Reader.Class
 import Control.Monad.State.Class
-import Control.Monad.Trans
-import Control.Monad.Writer.Class
 
--- ---------------------------------------------------------------------------
--- | A parameterizable state monad where /s/ is the type of the state
--- to carry and /a/ is the type of the /return value/.
-
-newtype State s a = State { runState :: s -> (a, s) }
-
--- |Evaluate this state monad with the given initial state,throwing
--- away the final state.  Very much like @fst@ composed with
--- @runstate@.
-
-evalState :: State s a -- ^The state to evaluate
-          -> s         -- ^An initial value
-          -> a         -- ^The return value of the state application
-evalState m s = fst (runState m s)
-
--- |Execute this state and return the new state, throwing away the
--- return value.  Very much like @snd@ composed with
--- @runstate@.
-
-execState :: State s a -- ^The state to evaluate
-          -> s         -- ^An initial value
-          -> s         -- ^The new state
-execState m s = snd (runState m s)
-
--- |Map a stateful computation from one (return value, state) pair to
--- another.  For instance, to convert numberTree from a function that
--- returns a tree to a function that returns the sum of the numbered
--- tree (see the Examples section for numberTree and sumTree) you may
--- write:
---
--- > sumNumberedTree :: (Eq a) => Tree a -> State (Table a) Int
--- > sumNumberedTree = mapState (\ (t, tab) -> (sumTree t, tab))  . numberTree
-
-mapState :: ((a, s) -> (b, s)) -> State s a -> State s b
-mapState f m = State $ f . runState m
-
--- |Apply this function to this state and return the resulting state.
-withState :: (s -> s) -> State s a -> State s a
-withState f m = State $ runState m . f
-
-
-instance Functor (State s) where
-    fmap f m = State $ \s -> case runState m s of
-                                 (a, s') -> (f a, s')
-
-instance Monad (State s) where
-    return a = State $ \s -> (a, s)
-    m >>= k  = State $ \s -> case runState m s of
-                                 (a, s') -> runState (k a) s'
-
-instance MonadFix (State s) where
-    mfix f = State $ \s -> let (a, s') = runState (f a) s in (a, s')
-
-instance MonadState s (State s) where
-    get   = State $ \s -> (s, s)
-    put s = State $ \_ -> ((), s)
-
--- ---------------------------------------------------------------------------
--- | A parameterizable state monad for encapsulating an inner
--- monad.
---
--- The StateT Monad structure is parameterized over two things:
---
---   * s - The state.
---
---   * m - The inner monad.
---
--- Here are some examples of use:
---
--- (Parser from ParseLib with Hugs)
---
--- >  type Parser a = StateT String [] a
--- >     ==> StateT (String -> [(a,String)])
---
--- For example, item can be written as:
---
--- >   item = do (x:xs) <- get
--- >          put xs
--- >          return x
--- >
--- >   type BoringState s a = StateT s Indentity a
--- >        ==> StateT (s -> Identity (a,s))
--- >
--- >   type StateWithIO s a = StateT s IO a
--- >        ==> StateT (s -> IO (a,s))
--- >
--- >   type StateWithErr s a = StateT s Maybe a
--- >        ==> StateT (s -> Maybe (a,s))
-
-newtype StateT s m a = StateT { runStateT :: s -> m (a,s) }
-
--- |Similar to 'evalState'
-evalStateT :: (Monad m) => StateT s m a -> s -> m a
-evalStateT m s = do
-    (a, _) <- runStateT m s
-    return a
-
--- |Similar to 'execState'
-execStateT :: (Monad m) => StateT s m a -> s -> m s
-execStateT m s = do
-    (_, s') <- runStateT m s
-    return s'
-
--- |Similar to 'mapState'
-mapStateT :: (m (a, s) -> n (b, s)) -> StateT s m a -> StateT s n b
-mapStateT f m = StateT $ f . runStateT m
-
--- |Similar to 'withState'
-withStateT :: (s -> s) -> StateT s m a -> StateT s m a
-withStateT f m = StateT $ runStateT m . f
-
-instance (Monad m) => Functor (StateT s m) where
-    fmap f m = StateT $ \s -> do
-        (x, s') <- runStateT m s
-        return (f x, s')
-
-instance (Monad m) => Monad (StateT s m) where
-    return a = StateT $ \s -> return (a, s)
-    m >>= k  = StateT $ \s -> do
-        (a, s') <- runStateT m s
-        runStateT (k a) s'
-    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
-
-instance (MonadFix m) => MonadFix (StateT s m) where
-    mfix f = StateT $ \s -> mfix $ \ ~(a, _) -> runStateT (f a) s
-
-instance (Monad m) => MonadState s (StateT s m) where
-    get   = StateT $ \s -> return (s, s)
-    put s = StateT $ \_ -> return ((), s)
-
--- ---------------------------------------------------------------------------
--- Instances for other mtl transformers
-
-instance MonadTrans (StateT s) where
-    lift m = StateT $ \s -> do
-        a <- m
-        return (a, s)
-
-instance (MonadIO m) => MonadIO (StateT s m) where
-    liftIO = lift . liftIO
-
-instance (MonadCont m) => MonadCont (StateT s m) where
-    callCC f = StateT $ \s ->
-        callCC $ \c ->
-        runStateT (f (\a -> StateT $ \s' -> c (a, s'))) s
-
-instance (MonadError e m) => MonadError e (StateT s m) where
-    throwError       = lift . throwError
-    m `catchError` h = StateT $ \s -> runStateT m s
-        `catchError` \e -> runStateT (h e) s
-
--- Needs UndecidableInstances
-instance (MonadReader r m) => MonadReader r (StateT s m) where
-    ask       = lift ask
-    local f m = StateT $ \s -> local f (runStateT m s)
+import Control.Monad.Trans
+import Control.Monad.Trans.State.Strict
+        (State, runState, evalState, execState, mapState, withState,
+         StateT(..), evalStateT, execStateT, mapStateT, withStateT)
 
--- Needs UndecidableInstances
-instance (MonadWriter w m) => MonadWriter w (StateT s m) where
-    tell     = lift . tell
-    listen m = StateT $ \s -> do
-        ((a, s'), w) <- listen (runStateT m s)
-        return ((a, w), s')
-    pass   m = StateT $ \s -> pass $ do
-        ((a, f), s') <- runStateT m s
-        return ((a, s'), f)
+import Control.Monad
+import Control.Monad.Fix
 
 -- ---------------------------------------------------------------------------
 -- $examples
diff --git a/Control/Monad/Trans.hs b/Control/Monad/Trans.hs
--- a/Control/Monad/Trans.hs
+++ b/Control/Monad/Trans.hs
@@ -3,38 +3,32 @@
 -- Module      :  Control.Monad.Trans
 -- Copyright   :  (c) Andy Gill 2001,
 --                (c) Oregon Graduate Institute of Science and Technology, 2001
--- License     :  BSD-style (see the file libraries/base/LICENSE)
+-- License     :  BSD-style (see the file LICENSE)
 --
 -- Maintainer  :  libraries@haskell.org
 -- Stability   :  experimental
 -- Portability :  portable
 --
--- The MonadTrans class.
+-- Classes for monad transformers.
 --
---      Inspired by the paper
---      /Functional Programming with Overloading and
---          Higher-Order Polymorphism/,
---        Mark P Jones (<http://web.cecs.pdx.edu/~mpj/>)
---          Advanced School of Functional Programming, 1995.
+-- A monad transformer makes 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
+-- 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 (
-    MonadTrans(..),
-    MonadIO(..),
+    module Control.Monad.Trans.Class,
+    module Control.Monad.IO.Class
   ) where
 
--- ---------------------------------------------------------------------------
--- MonadTrans class
---
--- Monad to facilitate stackable Monads.
--- Provides a way of digging into an outer
--- monad, giving access to (lifting) the inner monad.
-
-class MonadTrans t where
-    lift :: Monad m => m a -> t m a
-
-class (Monad m) => MonadIO m where
-    liftIO :: IO a -> m a
-
-instance MonadIO IO where
-    liftIO = id
+import Control.Monad.IO.Class
+import Control.Monad.Trans.Class
diff --git a/Control/Monad/Writer.hs b/Control/Monad/Writer.hs
--- a/Control/Monad/Writer.hs
+++ b/Control/Monad/Writer.hs
@@ -1,12 +1,9 @@
-{-# LANGUAGE UndecidableInstances #-}
--- Search for UndecidableInstances to see why this is needed
-
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Control.Monad.Writer
 -- Copyright   :  (c) Andy Gill 2001,
 --                (c) Oregon Graduate Institute of Science and Technology, 2001
--- License     :  BSD-style (see the file libraries/base/LICENSE)
+-- License     :  BSD-style (see the file LICENSE)
 --
 -- Maintainer  :  libraries@haskell.org
 -- Stability   :  experimental
@@ -26,4 +23,3 @@
   ) where
 
 import Control.Monad.Writer.Lazy
-
diff --git a/Control/Monad/Writer/Class.hs b/Control/Monad/Writer/Class.hs
--- a/Control/Monad/Writer/Class.hs
+++ b/Control/Monad/Writer/Class.hs
@@ -6,7 +6,7 @@
 -- Module      :  Control.Monad.Writer.Class
 -- Copyright   :  (c) Andy Gill 2001,
 --                (c) Oregon Graduate Institute of Science and Technology, 2001
--- License     :  BSD-style (see the file libraries/base/LICENSE)
+-- License     :  BSD-style (see the file LICENSE)
 --
 -- Maintainer  :  libraries@haskell.org
 -- Stability   :  experimental
@@ -27,6 +27,23 @@
     censor,
   ) where
 
+import Control.Monad.Trans.Error as Error
+import Control.Monad.Trans.Identity as Identity
+import Control.Monad.Trans.Maybe as Maybe
+import Control.Monad.Trans.Reader
+import qualified Control.Monad.Trans.RWS.Lazy as LazyRWS (
+        RWST, tell, listen, pass)
+import qualified Control.Monad.Trans.RWS.Strict as StrictRWS (
+        RWST, tell, listen, pass)
+import Control.Monad.Trans.State.Lazy as Lazy
+import Control.Monad.Trans.State.Strict as Strict
+import qualified Control.Monad.Trans.Writer.Lazy as Lazy (
+        WriterT, tell, listen, pass)
+import qualified Control.Monad.Trans.Writer.Strict as Strict (
+        WriterT, tell, listen, pass)
+
+import Control.Monad.Trans.Class (lift)
+import Control.Monad
 import Data.Monoid
 
 -- ---------------------------------------------------------------------------
@@ -34,7 +51,7 @@
 --
 -- tell is like tell on the MUD's it shouts to monad
 -- what you want to be heard. The monad carries this 'packet'
--- upwards, merging it if needed (hence the Monoid requirement)}
+-- upwards, merging it if needed (hence the Monoid requirement).
 --
 -- listen listens to a monad acting, and returns what the monad "said".
 --
@@ -42,17 +59,87 @@
 -- the written object.
 
 class (Monoid w, Monad m) => MonadWriter w m | m -> w where
+    -- | @'tell' w@ is an action that produces the output @w@.
     tell   :: w -> m ()
+    -- | @'listen' m@ is an action that executes the action @m@ and adds
+    -- its output to the value of the computation.
     listen :: m a -> m (a, w)
+    -- | @'pass' m@ is an action that executes the action @m@, which
+    -- returns a value and a function, and returns the value, applying
+    -- the function to the output.
     pass   :: m (a, w -> w) -> m a
 
+-- | @'listens' f m@ is an action that executes the action @m@ and adds
+-- the result of applying @f@ to the output to the value of the computation.
+--
+-- * @'listens' f m = 'liftM' (id *** f) ('listen' m)@
 listens :: (MonadWriter w m) => (w -> b) -> m a -> m (a, b)
 listens f m = do
     ~(a, w) <- listen m
     return (a, f w)
 
+-- | @'censor' f m@ is an action that executes the action @m@ and
+-- applies the function @f@ to its output, leaving the return value
+-- unchanged.
+--
+-- * @'censor' f m = 'pass' ('liftM' (\\x -> (x,f)) m)@
 censor :: (MonadWriter w m) => (w -> w) -> m a -> m a
 censor f m = pass $ do
     a <- m
     return (a, f)
 
+instance (Monoid w, Monad m) => MonadWriter w (Lazy.WriterT w m) where
+    tell   = Lazy.tell
+    listen = Lazy.listen
+    pass   = Lazy.pass
+
+instance (Monoid w, Monad m) => MonadWriter w (Strict.WriterT w m) where
+    tell   = Strict.tell
+    listen = Strict.listen
+    pass   = Strict.pass
+
+instance (Monoid w, Monad m) => MonadWriter w (LazyRWS.RWST r w s m) where
+    tell   = LazyRWS.tell
+    listen = LazyRWS.listen
+    pass   = LazyRWS.pass
+
+instance (Monoid w, Monad m) => MonadWriter w (StrictRWS.RWST r w s m) where
+    tell   = StrictRWS.tell
+    listen = StrictRWS.listen
+    pass   = StrictRWS.pass
+
+-- ---------------------------------------------------------------------------
+-- Instances for other mtl transformers
+--
+-- All of these instances need UndecidableInstances,
+-- because they do not satisfy the coverage condition.
+
+instance (Error e, MonadWriter w m) => MonadWriter w (ErrorT e m) where
+    tell   = lift . tell
+    listen = Error.liftListen listen
+    pass   = Error.liftPass pass
+
+instance (MonadWriter w m) => MonadWriter w (IdentityT m) where
+    tell   = lift . tell
+    listen = Identity.mapIdentityT listen
+    pass   = Identity.mapIdentityT pass
+
+instance (MonadWriter w m) => MonadWriter w (MaybeT m) where
+    tell   = lift . tell
+    listen = Maybe.liftListen listen
+    pass   = Maybe.liftPass pass
+
+instance (MonadWriter w m) => MonadWriter w (ReaderT r m) where
+    tell   = lift . tell
+    listen = mapReaderT listen
+    pass   = mapReaderT pass
+
+instance (MonadWriter w m) => MonadWriter w (Lazy.StateT s m) where
+    tell   = lift . tell
+    listen = Lazy.liftListen listen
+    pass   = Lazy.liftPass pass
+
+instance (MonadWriter w m) => MonadWriter w (Strict.StateT s m) where
+    tell   = lift . tell
+    listen = Strict.liftListen listen
+    pass   = Strict.liftPass pass
diff --git a/Control/Monad/Writer/Lazy.hs b/Control/Monad/Writer/Lazy.hs
--- a/Control/Monad/Writer/Lazy.hs
+++ b/Control/Monad/Writer/Lazy.hs
@@ -1,12 +1,9 @@
-{-# LANGUAGE UndecidableInstances #-}
--- Search for UndecidableInstances to see why this is needed
-
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Control.Monad.Writer.Lazy
 -- Copyright   :  (c) Andy Gill 2001,
 --                (c) Oregon Graduate Institute of Science and Technology, 2001
--- License     :  BSD-style (see the file libraries/base/LICENSE)
+-- License     :  BSD-style (see the file LICENSE)
 --
 -- Maintainer  :  libraries@haskell.org
 -- Stability   :  experimental
@@ -22,10 +19,16 @@
 -----------------------------------------------------------------------------
 
 module Control.Monad.Writer.Lazy (
-    module Control.Monad.Writer.Class,
-    Writer(..),
+    -- * MonadWriter class
+    MonadWriter(..),
+    listens,
+    censor,
+    -- * The Writer monad
+    Writer,
+    runWriter,
     execWriter,
     mapWriter,
+    -- * The WriterT monad transformer
     WriterT(..),
     execWriterT,
     mapWriterT,
@@ -35,116 +38,13 @@
     module Data.Monoid,
   ) where
 
-import Control.Monad
-import Control.Monad.Cont.Class
-import Control.Monad.Error.Class
-import Control.Monad.Fix
-import Control.Monad.Reader.Class
-import Control.Monad.State.Class
-import Control.Monad.Trans
 import Control.Monad.Writer.Class
-import Data.Monoid
 
--- ---------------------------------------------------------------------------
--- Our parameterizable writer monad
-
-newtype Writer w a = Writer { runWriter :: (a, w) }
-
-execWriter :: Writer w a -> w
-execWriter m = snd (runWriter m)
-
-mapWriter :: ((a, w) -> (b, w')) -> Writer w a -> Writer w' b
-mapWriter f m = Writer $ f (runWriter m)
-
-instance Functor (Writer w) where
-    fmap f m = Writer $ let (a, w) = runWriter m in (f a, w)
-
-instance (Monoid w) => Monad (Writer w) where
-    return a = Writer (a, mempty)
-    m >>= k  = Writer $ let
-        (a, w)  = runWriter m
-        (b, w') = runWriter (k a)
-        in (b, w `mappend` w')
-
-instance (Monoid w) => MonadFix (Writer w) where
-    mfix m = Writer $ let (a, w) = runWriter (m a) in (a, w)
-
-instance (Monoid w) => MonadWriter w (Writer w) where
-    tell   w = Writer ((), w)
-    listen m = Writer $ let (a, w) = runWriter m in ((a, w), w)
-    pass   m = Writer $ let ((a, f), w) = runWriter m in (a, f w)
-
--- ---------------------------------------------------------------------------
--- Our parameterizable writer monad, with an inner monad
-
-newtype WriterT w m a = WriterT { runWriterT :: m (a, w) }
-
-execWriterT :: Monad m => WriterT w m a -> m w
-execWriterT m = do
-    ~(_, w) <- runWriterT m
-    return w
-
-mapWriterT :: (m (a, w) -> n (b, w')) -> WriterT w m a -> WriterT w' n b
-mapWriterT f m = WriterT $ f (runWriterT m)
-
-instance (Monad m) => Functor (WriterT w m) where
-    fmap f m = WriterT $ do
-        ~(a, w) <- runWriterT m
-        return (f a, w)
-
-instance (Monoid w, Monad m) => Monad (WriterT w m) where
-    return a = WriterT $ return (a, mempty)
-    m >>= k  = WriterT $ do
-        ~(a, w)  <- runWriterT m
-        ~(b, w') <- runWriterT (k a)
-        return (b, w `mappend` w')
-    fail msg = WriterT $ fail msg
-
-instance (Monoid w, MonadPlus m) => MonadPlus (WriterT w m) where
-    mzero       = WriterT mzero
-    m `mplus` n = WriterT $ runWriterT m `mplus` runWriterT n
-
-instance (Monoid w, MonadFix m) => MonadFix (WriterT w m) where
-    mfix m = WriterT $ mfix $ \ ~(a, _) -> runWriterT (m a)
-
-instance (Monoid w, Monad m) => MonadWriter w (WriterT w m) where
-    tell   w = WriterT $ return ((), w)
-    listen m = WriterT $ do
-        ~(a, w) <- runWriterT m
-        return ((a, w), w)
-    pass   m = WriterT $ do
-        ~((a, f), w) <- runWriterT m
-        return (a, f w)
-
--- ---------------------------------------------------------------------------
--- Instances for other mtl transformers
-
-instance (Monoid w) => MonadTrans (WriterT w) where
-    lift m = WriterT $ do
-        a <- m
-        return (a, mempty)
-
-instance (Monoid w, MonadIO m) => MonadIO (WriterT w m) where
-    liftIO = lift . liftIO
-
-instance (Monoid w, MonadCont m) => MonadCont (WriterT w m) where
-    callCC f = WriterT $
-        callCC $ \c ->
-        runWriterT (f (\a -> WriterT $ c (a, mempty)))
-
-instance (Monoid w, MonadError e m) => MonadError e (WriterT w m) where
-    throwError       = lift . throwError
-    m `catchError` h = WriterT $ runWriterT m
-        `catchError` \e -> runWriterT (h e)
-
--- This instance needs UndecidableInstances, because
--- it does not satisfy the coverage condition
-instance (Monoid w, MonadReader r m) => MonadReader r (WriterT w m) where
-    ask       = lift ask
-    local f m = WriterT $ local f (runWriterT m)
-
--- Needs UndecidableInstances
-instance (Monoid w, MonadState s m) => MonadState s (WriterT w m) where
-    get = lift get
-    put = lift . put
+import Control.Monad.Trans
+import Control.Monad.Trans.Writer.Lazy (
+        Writer, runWriter, execWriter, mapWriter,
+        WriterT(..), execWriterT, mapWriterT)
 
+import Control.Monad
+import Control.Monad.Fix
+import Data.Monoid
diff --git a/Control/Monad/Writer/Strict.hs b/Control/Monad/Writer/Strict.hs
--- a/Control/Monad/Writer/Strict.hs
+++ b/Control/Monad/Writer/Strict.hs
@@ -1,12 +1,9 @@
-{-# LANGUAGE UndecidableInstances #-}
--- Search for UndecidableInstances to see why this is needed
-
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Control.Monad.Writer.Strict
 -- Copyright   :  (c) Andy Gill 2001,
 --                (c) Oregon Graduate Institute of Science and Technology, 2001
--- License     :  BSD-style (see the file libraries/base/LICENSE)
+-- License     :  BSD-style (see the file LICENSE)
 --
 -- Maintainer  :  libraries@haskell.org
 -- Stability   :  experimental
@@ -22,10 +19,16 @@
 -----------------------------------------------------------------------------
 
 module Control.Monad.Writer.Strict (
-    module Control.Monad.Writer.Class,
-    Writer(..),
+    -- * MonadWriter class
+    MonadWriter(..),
+    listens,
+    censor,
+    -- * The Writer monad
+    Writer,
+    runWriter,
     execWriter,
     mapWriter,
+    -- * The WriterT monad transformer
     WriterT(..),
     execWriterT,
     mapWriterT,
@@ -35,118 +38,13 @@
     module Data.Monoid,
   ) where
 
-import Control.Monad
-import Control.Monad.Cont.Class
-import Control.Monad.Error.Class
-import Control.Monad.Fix
-import Control.Monad.Reader.Class
-import Control.Monad.State.Class
-import Control.Monad.Trans
 import Control.Monad.Writer.Class
-import Data.Monoid
 
--- ---------------------------------------------------------------------------
--- Our parameterizable writer monad
-
-newtype Writer w a = Writer { runWriter :: (a, w) }
-
-execWriter :: Writer w a -> w
-execWriter m = snd (runWriter m)
-
-mapWriter :: ((a, w) -> (b, w')) -> Writer w a -> Writer w' b
-mapWriter f m = Writer $ f (runWriter m)
-
-instance Functor (Writer w) where
-    fmap f m = Writer $ case runWriter m of
-                            (a, w) -> (f a, w)
-
-instance (Monoid w) => Monad (Writer w) where
-    return a = Writer (a, mempty)
-    m >>= k  = Writer $ case runWriter m of
-                            (a, w) -> case runWriter (k a) of
-                                (b, w') -> (b, w `mappend` w')
-
-instance (Monoid w) => MonadFix (Writer w) where
-    mfix m = Writer $ let (a, w) = runWriter (m a) in (a, w)
-
-instance (Monoid w) => MonadWriter w (Writer w) where
-    tell   w = Writer ((), w)
-    listen m = Writer $ case runWriter m of
-                            (a, w) -> ((a, w), w)
-    pass   m = Writer $ case runWriter m of
-                            ((a, f), w) -> (a, f w)
-
--- ---------------------------------------------------------------------------
--- Our parameterizable writer monad, with an inner monad
-
-newtype WriterT w m a = WriterT { runWriterT :: m (a, w) }
-
-execWriterT :: Monad m => WriterT w m a -> m w
-execWriterT m = do
-    (_, w) <- runWriterT m
-    return w
-
-mapWriterT :: (m (a, w) -> n (b, w')) -> WriterT w m a -> WriterT w' n b
-mapWriterT f m = WriterT $ f (runWriterT m)
-
-instance (Monad m) => Functor (WriterT w m) where
-    fmap f m = WriterT $ do
-        (a, w) <- runWriterT m
-        return (f a, w)
-
-instance (Monoid w, Monad m) => Monad (WriterT w m) where
-    return a = WriterT $ return (a, mempty)
-    m >>= k  = WriterT $ do
-        (a, w)  <- runWriterT m
-        (b, w') <- runWriterT (k a)
-        return (b, w `mappend` w')
-    fail msg = WriterT $ fail msg
-
-instance (Monoid w, MonadPlus m) => MonadPlus (WriterT w m) where
-    mzero       = WriterT mzero
-    m `mplus` n = WriterT $ runWriterT m `mplus` runWriterT n
-
-instance (Monoid w, MonadFix m) => MonadFix (WriterT w m) where
-    mfix m = WriterT $ mfix $ \ ~(a, _) -> runWriterT (m a)
-
-instance (Monoid w, Monad m) => MonadWriter w (WriterT w m) where
-    tell   w = WriterT $ return ((), w)
-    listen m = WriterT $ do
-        (a, w) <- runWriterT m
-        return ((a, w), w)
-    pass   m = WriterT $ do
-        ((a, f), w) <- runWriterT m
-        return (a, f w)
-
--- ---------------------------------------------------------------------------
--- Instances for other mtl transformers
-
-instance (Monoid w) => MonadTrans (WriterT w) where
-    lift m = WriterT $ do
-        a <- m
-        return (a, mempty)
-
-instance (Monoid w, MonadIO m) => MonadIO (WriterT w m) where
-    liftIO = lift . liftIO
-
-instance (Monoid w, MonadCont m) => MonadCont (WriterT w m) where
-    callCC f = WriterT $
-        callCC $ \c ->
-        runWriterT (f (\a -> WriterT $ c (a, mempty)))
-
-instance (Monoid w, MonadError e m) => MonadError e (WriterT w m) where
-    throwError       = lift . throwError
-    m `catchError` h = WriterT $ runWriterT m
-        `catchError` \e -> runWriterT (h e)
-
--- This instance needs UndecidableInstances, because
--- it does not satisfy the coverage condition
-instance (Monoid w, MonadReader r m) => MonadReader r (WriterT w m) where
-    ask       = lift ask
-    local f m = WriterT $ local f (runWriterT m)
-
--- Needs UndecidableInstances
-instance (Monoid w, MonadState s m) => MonadState s (WriterT w m) where
-    get = lift get
-    put = lift . put
+import Control.Monad.Trans
+import Control.Monad.Trans.Writer.Strict (
+        Writer, runWriter, execWriter, mapWriter,
+        WriterT(..), execWriterT, mapWriterT)
 
+import Control.Monad
+import Control.Monad.Fix
+import Data.Monoid
diff --git a/Setup.hs b/Setup.hs
--- a/Setup.hs
+++ b/Setup.hs
@@ -1,6 +1,2 @@
-module Main (main) where
-
 import Distribution.Simple
-
-main :: IO ()
 main = defaultMain
diff --git a/mtl.cabal b/mtl.cabal
--- a/mtl.cabal
+++ b/mtl.cabal
@@ -1,18 +1,19 @@
 name:         mtl
-version:      1.1.1.1
+version:      2.0.0.0
+cabal-version: >= 1.6
 license:      BSD3
 license-file: LICENSE
 author:       Andy Gill
 maintainer:   libraries@haskell.org
 category:     Control
-synopsis:     Monad transformer library
+synopsis:     Monad classes, using functional dependencies
 description:
-    A monad transformer library, inspired by the paper /Functional
-    Programming with Overloading and Higher-Order Polymorphism/,
-    by Mark P Jones (<http://web.cecs.pdx.edu/~mpj/pubs/springschool.html>),
-    Advanced School of Functional Programming, 1995.
+    Monad classes using functional dependencies, with instances
+    for various monad transformers, inspired by the paper
+    /Functional Programming with Overloading and Higher-Order Polymorphism/,
+    by Mark P Jones, in /Advanced School of Functional Programming/, 1995
+    (<http://web.cecs.pdx.edu/~mpj/pubs/springschool.html>).
 build-type: Simple
-ghc-options: -Wall
 exposed-modules:
     Control.Monad.Cont
     Control.Monad.Cont.Class
@@ -35,9 +36,8 @@
     Control.Monad.Writer.Class
     Control.Monad.Writer.Lazy
     Control.Monad.Writer.Strict
-build-depends: base < 5
-extensions: MultiParamTypeClasses,
-            FunctionalDependencies,
-            FlexibleInstances,
-            TypeSynonymInstances
-
+build-depends: base < 6, transformers == 0.2.*
+extensions:
+    MultiParamTypeClasses
+    FunctionalDependencies
+    FlexibleInstances
