diff --git a/Control/Monad/Catch.hs b/Control/Monad/Catch.hs
--- a/Control/Monad/Catch.hs
+++ b/Control/Monad/Catch.hs
@@ -2,115 +2,30 @@
 #ifdef LANGUAGE_ConstraintKinds
 {-# LANGUAGE ConstraintKinds #-}
 #endif
-#ifdef LANGUAGE_DefaultSignatures
-{-# LANGUAGE DefaultSignatures #-}
-#endif
 {-# LANGUAGE
     FlexibleInstances
-  , FunctionalDependencies
   , MultiParamTypeClasses
   , UndecidableInstances #-}
-{- |
-License: BSD-style (see the file LICENSE)
-Maintainer: Andy Sonnenburg <andy22286@gmail.com>
-Stability: experimental
-Portability: non-portable
-
-[Computation type:]
-Computations which may fail or throw exceptions; and computations which may
-catch failures and thrown exceptions.
-
-[Binding strategy:]
-Failure records information about the cause/location of the failure.  Failure
-values bypass the bound function; other values are used as inputs to the bound
-function (same as @'Control.Monad.Error.Class.MonadError'@).
-
-[Useful for:]
-Building computations from sequences of functions that may fail; and using
-exception handling to structure error handling.  The handler may or may not
-throw an exception, which does not have to be of the same type as the original
-thrown exception (see @'mapE'@).
-
-[Zero and plus:]
-Zero is represented by an empty error, and the plus operation executes its
-second argument if the first fails (same as
-@'Control.Monad.Error.Class.MonadError'@).
-
-[Example type:]
-@'Either' 'String' a@
-
-The Throw and Catch monads.
--}
 module Control.Monad.Catch
-       ( MonadThrow (..)
+       ( module Exports
+       , MonadThrow (..)
        , MonadCatch (..)
-       , MonadError
        , mapE
+       , MonadError
        , WrappedMonadError (..)
        , WrappedMonadCatch (..)
        ) where
 
-import Control.Exception (IOException, ioError)
-import qualified Control.Exception as Exception
-import Control.Monad
+import Control.Applicative
+import Control.Monad as Exports
+import Control.Monad.Catch.Class
+import Control.Monad.Cont.Class
 import qualified Control.Monad.Error.Class as Error
-import Control.Monad.Trans.Class
-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
-import qualified Control.Monad.Trans.RWS.Strict as StrictRWS
-import qualified Control.Monad.Trans.State.Lazy as LazyState
-import qualified Control.Monad.Trans.State.Strict as StrictState
-import qualified Control.Monad.Trans.Writer.Lazy as LazyWriter
-import qualified Control.Monad.Trans.Writer.Strict as StrictWriter
-
-import Data.Monoid
-
-import Prelude (Either (..), IO, ($), (.), either)
-
-{- |
-The strategy of combining computations that can throw exceptions.
-
-Is parameterized over the type of error information and the monad type
-constructor.  It is common to use @'Either' 'String'@.  In some cases you will
-have to define an instance of @'MonadThrow'@, though rarely a definition of
-@'throw'@
--}
-class Monad m => MonadThrow e m | m -> e where
-  {- |
-  Is used within a monadic computation to begin exception processing.  If
-  @('MonadThrow' e n, 'MonadTrans' t) => t n ~ m@, then @'throw' = 'lift' '.'
-  'throw'@ is the default definition.
-  -}
-  throw :: e -> m a
-#ifdef LANGUAGE_DefaultSignatures
-  default throw :: (MonadThrow e m, MonadTrans t) => e -> t m a
-  throw = lift . throw
-#endif
-
-{- |
-The strategy of combining computations that can handle thrown exceptions,
-as well as throwing exceptions in the original computation.
-
-Is parameterized over the type of error information and the original monad type
-constructor, as well as the handler monad type constructor.  The handler monad
-type constructor commonly differs from the original monad type constructor due
-to a change in the type of the error information.
--}
-class (MonadThrow e m, Monad n) => MonadCatch e m n | n e -> m where
-  {- |
-  A handler function to handle thrown values and return to normal execution.
-  A common idiom is:
-
-  > do { action1; action2; action3 } `catch` handler
+import Control.Monad.Fix as Exports
+import Control.Monad.RWS.Class
+import Control.Monad.Trans as Exports
 
-  where the @action@ functions can call 'throw'.
-  Note that @handler@ and the do-block must have the same return type.
-  -}
-  catch :: m a -> (e -> n a) -> n a
+import Prelude (($), (.))
 
 #ifdef LANGUAGE_ConstraintKinds
 type MonadError e m = (MonadThrow e m, MonadCatch e m m)
@@ -119,126 +34,38 @@
 instance (MonadThrow e m, MonadCatch e m m) => MonadError e m
 #endif
 
--- | Map the thrown value using the given function
-mapE :: (MonadCatch e m n, MonadThrow e' n) => (e -> e') -> m a -> n a
-mapE f m = m `catch` (throw . f)
-
-instance MonadThrow IOException IO where
-  throw = ioError
-instance MonadCatch IOException IO IO where
-  catch = Exception.catch
-
-instance MonadThrow e (Either e) where
-  throw = Left
-instance MonadCatch e (Either e) (Either e') where
-  Left e `catch` h = h e
-  Right a `catch` _h = Right a
-
-instance (Error e, Monad m) => MonadThrow e (ErrorT e m) where
-  throw = throwError
-instance ( Error e
-         , Error e'
-         , Monad m
-         ) => MonadCatch e (ErrorT e m) (ErrorT e' m) where
-  m `catch` h = ErrorT $ runErrorT m >>= either (runErrorT . h) (return . Right)
-
-instance MonadThrow e m => MonadThrow e (IdentityT m)
-#ifndef LANGUAGE_DefaultSignatures
-  where throw = lift . throw
-#endif
-instance MonadCatch e m n => MonadCatch e (IdentityT m) (IdentityT n) where
-  m `catch` h = IdentityT $ runIdentityT m `catch` (runIdentityT . h)
-
-instance MonadThrow e m => MonadThrow e (ListT m)
-#ifndef LANGUAGE_DefaultSignatures
-  where throw = lift . throw
-#endif
-instance MonadCatch e m n => MonadCatch e (ListT m) (ListT n) where
-  m `catch` h = ListT $ runListT m `catch` \ e -> runListT (h e)
-
-instance MonadThrow e m => MonadThrow e (MaybeT m)
-#ifndef LANGUAGE_DefaultSignatures
-  where throw = lift . throw
-#endif
-instance MonadCatch e m n => MonadCatch e (MaybeT m) (MaybeT n) where
-  m `catch` h = MaybeT $ runMaybeT m `catch` (runMaybeT . h)
-
-instance MonadThrow e m => MonadThrow e (ReaderT r m)
-#ifndef LANGUAGE_DefaultSignatures
-  where throw = lift . throw
-#endif
-instance MonadCatch e m n => MonadCatch e (ReaderT r m) (ReaderT r n) where
-  m `catch` h =
-    ReaderT $ \ r -> runReaderT m r `catch` \ e -> runReaderT (h e) r
-
-instance (Monoid w, MonadThrow e m) => MonadThrow e (LazyRWS.RWST r w s m)
-#ifndef LANGUAGE_DefaultSignatures
-  where throw = lift . throw
-#endif
-instance (Monoid w, MonadCatch e m n) =>
-         MonadCatch e (LazyRWS.RWST r w s m) (LazyRWS.RWST r w s n) where
-  m `catch` h = LazyRWS.RWST $ \ r s ->
-    LazyRWS.runRWST m r s `catch` \ e -> LazyRWS.runRWST (h e) r s
-
-instance (Monoid w, MonadThrow e m) => MonadThrow e (StrictRWS.RWST r w s m)
-#ifndef LANGUAGE_DefaultSignatures
-  where throw = lift . throw
-#endif
-instance (Monoid w, MonadCatch e m n) =>
-         MonadCatch e (StrictRWS.RWST r w s m) (StrictRWS.RWST r w s n) where
-  m `catch` h = StrictRWS.RWST $ \ r s ->
-    StrictRWS.runRWST m r s `catch` \ e -> StrictRWS.runRWST (h e) r s
-
-instance MonadThrow e m => MonadThrow e (LazyState.StateT s m)
-#ifndef LANGUAGE_DefaultSignatures
-  where throw = lift . throw
-#endif
-instance MonadCatch e m n =>
-         MonadCatch e (LazyState.StateT s m) (LazyState.StateT s n) where
-  m `catch` h = LazyState.StateT $ \ s ->
-    LazyState.runStateT m s `catch` \ e -> LazyState.runStateT (h e) s
-
-instance MonadThrow e m => MonadThrow e (StrictState.StateT s m)
-#ifndef LANGUAGE_DefaultSignatures
-  where throw = lift . throw
-#endif
-instance MonadCatch e m n =>
-         MonadCatch e (StrictState.StateT s m) (StrictState.StateT s n) where
-  m `catch` h = StrictState.StateT $ \ s ->
-    StrictState.runStateT m s `catch` \ e -> StrictState.runStateT (h e) s
-
-instance (Monoid w, MonadThrow e m) => MonadThrow e (LazyWriter.WriterT w m)
-#ifndef LANGUAGE_DefaultSignatures
-  where throw = lift . throw
-#endif
-instance
-  ( Monoid w
-  , MonadCatch e m n
-  ) => MonadCatch e (LazyWriter.WriterT w m) (LazyWriter.WriterT w n) where
-  m `catch` h =
-    LazyWriter.WriterT $
-    LazyWriter.runWriterT m `catch` (LazyWriter.runWriterT . h)
-
-instance (Monoid w, MonadThrow e m) => MonadThrow e (StrictWriter.WriterT w m)
-#ifndef LANGUAGE_DefaultSignatures
-  where throw = lift . throw
-#endif
-instance
-  ( Monoid w
-  , MonadCatch e m n
-  ) => MonadCatch e (StrictWriter.WriterT w m) (StrictWriter.WriterT w n) where
-  m `catch` h =
-    StrictWriter.WriterT $
-    StrictWriter.runWriterT m `catch` (StrictWriter.runWriterT . h)
-
 newtype WrappedMonadError m a =
   WrapMonadError { unwrapMonadError :: m a
                  }
 
+instance Functor m => Functor (WrappedMonadError m) where
+  fmap f = WrapMonadError . fmap f . unwrapMonadError
+  a <$ m = WrapMonadError $ a <$ unwrapMonadError m
+
+instance Applicative m => Applicative (WrappedMonadError m) where
+  pure = WrapMonadError . pure
+  f <*> a = WrapMonadError $ unwrapMonadError f <*> unwrapMonadError a
+  a *> b = WrapMonadError $ unwrapMonadError a *> unwrapMonadError b
+  a <* b = WrapMonadError $ unwrapMonadError a <* unwrapMonadError b
+
+instance Alternative m => Alternative (WrappedMonadError m) where
+  empty = WrapMonadError empty
+  m <|> n = WrapMonadError $ unwrapMonadError m <|> unwrapMonadError n
+  some = WrapMonadError . some . unwrapMonadError
+  many = WrapMonadError . many . unwrapMonadError
+
 instance Monad m => Monad (WrappedMonadError m) where
   return = WrapMonadError . return
   m >>= f = WrapMonadError $ unwrapMonadError m >>= unwrapMonadError . f
+  m >> n = WrapMonadError $ unwrapMonadError m >> unwrapMonadError n
+  fail = WrapMonadError . fail
 
+instance MonadTrans WrappedMonadError where
+  lift = WrapMonadError
+
+instance MonadIO m => MonadIO (WrappedMonadError m) where
+  liftIO = WrapMonadError . liftIO
+
 instance Error.MonadError e m => MonadThrow e (WrappedMonadError m) where
   throw = WrapMonadError . Error.throwError
 instance Error.MonadError e m =>
@@ -247,15 +74,96 @@
     WrapMonadError $
     unwrapMonadError m `Error.catchError` (unwrapMonadError . h)
 
+instance MonadCont m => MonadCont (WrappedMonadError m) where
+  callCC f =
+    WrapMonadError $ callCC $ \ c -> unwrapMonadError (f (WrapMonadError . c))
+
+instance Error.MonadError e m => Error.MonadError e (WrappedMonadError m) where
+  throwError = WrapMonadError . Error.throwError
+  m `catchError` h =
+    WrapMonadError $
+    unwrapMonadError m `Error.catchError` (unwrapMonadError . h)
+
+instance MonadRWS r w s m => MonadRWS r w s (WrappedMonadError m)
+
+instance MonadReader r m => MonadReader r (WrappedMonadError m) where
+  ask = WrapMonadError ask
+  local f = WrapMonadError . local f . unwrapMonadError
+  reader = WrapMonadError . reader
+
+instance MonadState s m => MonadState s (WrappedMonadError m) where
+  get = WrapMonadError get
+  put = WrapMonadError . put
+  state = WrapMonadError . state
+
+instance MonadWriter w m => MonadWriter w (WrappedMonadError m) where
+  writer = WrapMonadError . writer
+  tell = WrapMonadError . tell
+  listen = WrapMonadError . listen . unwrapMonadError
+  pass = WrapMonadError . pass . unwrapMonadError
+
 newtype WrappedMonadCatch m a =
   WrapMonadCatch { unwrapMonadCatch :: m a
                  }
 
+instance Functor m => Functor (WrappedMonadCatch m) where
+  fmap f = WrapMonadCatch . fmap f . unwrapMonadCatch
+  a <$ m = WrapMonadCatch $ a <$ unwrapMonadCatch m
+
+instance Applicative m => Applicative (WrappedMonadCatch m) where
+  pure = WrapMonadCatch . pure
+  f <*> a = WrapMonadCatch $ unwrapMonadCatch f <*> unwrapMonadCatch a
+  a *> b = WrapMonadCatch $ unwrapMonadCatch a *> unwrapMonadCatch b
+  a <* b = WrapMonadCatch $ unwrapMonadCatch a <* unwrapMonadCatch b
+
+instance Alternative m => Alternative (WrappedMonadCatch m) where
+  empty = WrapMonadCatch empty
+  m <|> n = WrapMonadCatch $ unwrapMonadCatch m <|> unwrapMonadCatch n
+  some = WrapMonadCatch . some . unwrapMonadCatch
+  many = WrapMonadCatch . many . unwrapMonadCatch
+
 instance Monad m => Monad (WrappedMonadCatch m) where
   return = WrapMonadCatch . return
   m >>= f = WrapMonadCatch $ unwrapMonadCatch m >>= unwrapMonadCatch . f
+  m >> n = WrapMonadCatch $ unwrapMonadCatch m >> unwrapMonadCatch n
+  fail = WrapMonadCatch . fail
 
+instance MonadTrans WrappedMonadCatch where
+  lift = WrapMonadCatch
+
+instance MonadIO m => MonadIO (WrappedMonadCatch m) where
+  liftIO = WrapMonadCatch . liftIO
+
+instance MonadThrow e m => MonadThrow e (WrappedMonadCatch m) where
+  throw = WrapMonadCatch . throw
+instance MonadCatch e m n =>
+         MonadCatch e (WrappedMonadCatch m) (WrappedMonadCatch n) where
+  m `catch` h =
+    WrapMonadCatch $ unwrapMonadCatch m `catch` (unwrapMonadCatch . h)
+
+instance MonadCont m => MonadCont (WrappedMonadCatch m) where
+  callCC f =
+    WrapMonadCatch $ callCC $ \ c -> unwrapMonadCatch (f (WrapMonadCatch . c))
+
 instance MonadCatch e m m => Error.MonadError e (WrappedMonadCatch m) where
   throwError = WrapMonadCatch . throw
   m `catchError` h =
     WrapMonadCatch $ unwrapMonadCatch m `catch` (unwrapMonadCatch . h)
+
+instance MonadRWS r w s m => MonadRWS r w s (WrappedMonadCatch m)
+
+instance MonadReader r m => MonadReader r (WrappedMonadCatch m) where
+  ask = WrapMonadCatch ask
+  local f = WrapMonadCatch . local f . unwrapMonadCatch
+  reader = WrapMonadCatch . reader
+
+instance MonadState s m => MonadState s (WrappedMonadCatch m) where
+  get = WrapMonadCatch get
+  put = WrapMonadCatch . put
+  state = WrapMonadCatch . state
+
+instance MonadWriter w m => MonadWriter w (WrappedMonadCatch m) where
+  writer = WrapMonadCatch . writer
+  tell = WrapMonadCatch . tell
+  listen = WrapMonadCatch . listen . unwrapMonadCatch
+  pass = WrapMonadCatch . pass . unwrapMonadCatch
diff --git a/Control/Monad/Catch/Class.hs b/Control/Monad/Catch/Class.hs
new file mode 100644
--- /dev/null
+++ b/Control/Monad/Catch/Class.hs
@@ -0,0 +1,226 @@
+{-# LANGUAGE CPP #-}
+#ifdef LANGUAGE_DefaultSignatures
+{-# LANGUAGE DefaultSignatures #-}
+#endif
+{-# LANGUAGE
+    FlexibleInstances
+  , FunctionalDependencies
+  , MultiParamTypeClasses
+  , UndecidableInstances #-}
+{- |
+License: BSD-style (see the file LICENSE)
+Maintainer: Andy Sonnenburg <andy22286@gmail.com>
+Stability: experimental
+Portability: non-portable
+
+[Computation type:]
+Computations which may fail or throw exceptions; and computations which may
+catch failures and thrown exceptions.
+
+[Binding strategy:]
+Failure records information about the cause/location of the failure.  Failure
+values bypass the bound function; other values are used as inputs to the bound
+function (same as @'Control.Monad.Error.Class.MonadError'@).
+
+[Useful for:]
+Building computations from sequences of functions that may fail; and using
+exception handling to structure error handling.  The handler may or may not
+throw an exception, which does not have to be of the same type as the original
+thrown exception (see @'mapE'@).
+
+[Zero and plus:]
+Zero is represented by an empty error, and the plus operation executes its
+second argument if the first fails (same as
+@'Control.Monad.Error.Class.MonadError'@).
+
+[Example type:]
+@'Either' 'String' a@
+
+The Throw and Catch monads.
+-}
+module Control.Monad.Catch.Class
+       ( MonadThrow (..)
+       , MonadCatch (..)
+       , mapE
+       ) where
+
+import Control.Exception (IOException, ioError)
+import qualified Control.Exception as Exception
+import Control.Monad
+import Control.Monad.Trans.Class
+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 Lazy (RWST (..))
+import qualified Control.Monad.Trans.RWS.Strict as Strict (RWST (..))
+import qualified Control.Monad.Trans.State.Lazy as Lazy (StateT (..))
+import qualified Control.Monad.Trans.State.Strict as Strict (StateT (..))
+import qualified Control.Monad.Trans.Writer.Lazy as Lazy (WriterT (..))
+import qualified Control.Monad.Trans.Writer.Strict as Strict (WriterT (..))
+
+import Data.Monoid (Monoid)
+
+import Prelude (Either (..), IO, ($), (.), either)
+
+{- |
+The strategy of combining computations that can throw exceptions.
+
+Is parameterized over the type of error information and the monad type
+constructor.  It is common to use @'Either' 'String'@.  In some cases you will
+have to define an instance of @'MonadThrow'@, though rarely a definition of
+@'throw'@
+-}
+class Monad m => MonadThrow e m | m -> e where
+  {- |
+  Is used within a monadic computation to begin exception processing.  If
+  @('MonadThrow' e n, 'MonadTrans' t) => t n ~ m@, then @'throw' = 'lift' '.'
+  'throw'@ is the default definition.
+  -}
+  throw :: e -> m a
+#ifdef LANGUAGE_DefaultSignatures
+  default throw :: (MonadThrow e m, MonadTrans t) => e -> t m a
+  throw = lift . throw
+#endif
+
+{- |
+The strategy of combining computations that can handle thrown exceptions,
+as well as throwing exceptions in the original computation.
+
+Is parameterized over the type of error information and the original monad type
+constructor, as well as the handler monad type constructor.  The handler monad
+type constructor commonly differs from the original monad type constructor due
+to a change in the type of the error information.
+-}
+class (MonadThrow e m, Monad n) => MonadCatch e m n | n e -> m where
+  {- |
+  A handler function to handle thrown values and return to normal execution.
+  A common idiom is:
+
+  > do { action1; action2; action3 } `catch` handler
+
+  where the @action@ functions can call 'throw'.
+  Note that @handler@ and the do-block must have the same return type.
+  -}
+  catch :: m a -> (e -> n a) -> n a
+
+-- | Map the thrown value using the given function
+mapE :: (MonadCatch e m n, MonadThrow e' n) => (e -> e') -> m a -> n a
+mapE f m = m `catch` (throw . f)
+
+instance MonadThrow IOException IO where
+  throw = ioError
+instance MonadCatch IOException IO IO where
+  catch = Exception.catch
+
+instance MonadThrow e (Either e) where
+  throw = Left
+instance MonadCatch e (Either e) (Either e') where
+  Left e `catch` h = h e
+  Right a `catch` _h = Right a
+
+instance (Error e, Monad m) => MonadThrow e (ErrorT e m) where
+  throw = throwError
+instance ( Error e
+         , Error e'
+         , Monad m
+         ) => MonadCatch e (ErrorT e m) (ErrorT e' m) where
+  m `catch` h = ErrorT $ runErrorT m >>= either (runErrorT . h) (return . Right)
+
+#ifdef LANGUAGE_DefaultSignatures
+#define MONAD_THROW(T)\
+instance MonadThrow e m => MonadThrow e (T m)
+#else
+#define MONAD_THROW(T)\
+instance MonadThrow e m => MonadThrow e (T m) where\
+  throw = lift . throw
+#endif
+MONAD_THROW(IdentityT)
+MONAD_THROW(ListT)
+MONAD_THROW(MaybeT)
+MONAD_THROW(ReaderT r)
+#undef MONAD_THROW
+
+#ifdef LANGUAGE_DefaultSignatures
+#define MONAD_THROW(C, T)\
+instance (C, MonadThrow e m) => MonadThrow e (T m)
+#else
+#define MONAD_THROW(C, T)\
+instance (C, MonadThrow e m) => MonadThrow e (T m) where\
+  throw = lift . throw
+#endif
+MONAD_THROW(Monoid w, Lazy.RWST r w s)
+MONAD_THROW(Monoid w, Strict.RWST r w s)
+#undef MONAD_THROW
+
+#ifdef LANGUAGE_DefaultSignatures
+#define MONAD_THROW(T)\
+instance MonadThrow e m => MonadThrow e (T m)
+#else
+#define MONAD_THROW(T)\
+instance MonadThrow e m => MonadThrow e (T m) where\
+  throw = lift . throw
+#endif
+MONAD_THROW(Lazy.StateT s)
+MONAD_THROW(Strict.StateT s)
+#undef MONAD_THROW
+
+#ifdef LANGUAGE_DefaultSignatures
+#define MONAD_THROW(C, T)\
+instance (C, MonadThrow e m) => MonadThrow e (T m)
+#else
+#define MONAD_THROW(C, T)\
+instance (C, MonadThrow e m) => MonadThrow e (T m) where\
+  throw = lift . throw
+#endif
+MONAD_THROW(Monoid w, Lazy.WriterT w)
+MONAD_THROW(Monoid w, Strict.WriterT w)
+#undef MONAD_THROW
+
+instance MonadCatch e m n => MonadCatch e (IdentityT m) (IdentityT n) where
+  m `catch` h = IdentityT $ runIdentityT m `catch` (runIdentityT . h)
+
+instance MonadCatch e m n => MonadCatch e (ListT m) (ListT n) where
+  m `catch` h = ListT $ runListT m `catch` \ e -> runListT (h e)
+
+instance MonadCatch e m n => MonadCatch e (MaybeT m) (MaybeT n) where
+  m `catch` h = MaybeT $ runMaybeT m `catch` (runMaybeT . h)
+
+instance MonadCatch e m n => MonadCatch e (ReaderT r m) (ReaderT r n) where
+  m `catch` h =
+    ReaderT $ \ r -> runReaderT m r `catch` \ e -> runReaderT (h e) r
+
+instance (Monoid w, MonadCatch e m n) =>
+         MonadCatch e (Lazy.RWST r w s m) (Lazy.RWST r w s n) where
+  m `catch` h = Lazy.RWST $ \ r s ->
+    Lazy.runRWST m r s `catch` \ e -> Lazy.runRWST (h e) r s
+
+instance (Monoid w, MonadCatch e m n) =>
+         MonadCatch e (Strict.RWST r w s m) (Strict.RWST r w s n) where
+  m `catch` h = Strict.RWST $ \ r s ->
+    Strict.runRWST m r s `catch` \ e -> Strict.runRWST (h e) r s
+
+instance MonadCatch e m n =>
+         MonadCatch e (Lazy.StateT s m) (Lazy.StateT s n) where
+  m `catch` h = Lazy.StateT $ \ s ->
+    Lazy.runStateT m s `catch` \ e -> Lazy.runStateT (h e) s
+
+instance MonadCatch e m n =>
+         MonadCatch e (Strict.StateT s m) (Strict.StateT s n) where
+  m `catch` h = Strict.StateT $ \ s ->
+    Strict.runStateT m s `catch` \ e -> Strict.runStateT (h e) s
+
+instance ( Monoid w
+         , MonadCatch e m n
+         ) => MonadCatch e (Lazy.WriterT w m) (Lazy.WriterT w n) where
+  m `catch` h =
+    Lazy.WriterT $
+    Lazy.runWriterT m `catch` (Lazy.runWriterT . h)
+
+instance ( Monoid w
+         , MonadCatch e m n
+         ) => MonadCatch e (Strict.WriterT w m) (Strict.WriterT w n) where
+  m `catch` h =
+    Strict.WriterT $
+    Strict.runWriterT m `catch` (Strict.runWriterT . h)
diff --git a/catch-fd.cabal b/catch-fd.cabal
--- a/catch-fd.cabal
+++ b/catch-fd.cabal
@@ -1,5 +1,5 @@
 name:                catch-fd
-version:             0.1.0.2
+version:             0.2.0.0
 cabal-version:       >= 1.10
 synopsis:            MonadThrow and MonadCatch, using functional dependencies
 description:         MonadThrow and MonadCatch, using functional dependencies
@@ -18,7 +18,9 @@
 
 library
   default-language: Haskell98
-  exposed-modules: Control.Monad.Catch
+  exposed-modules:
+    Control.Monad.Catch
+    Control.Monad.Catch.Class
   build-depends:
     base >= 4 && < 5,
     transformers >= 0.2 && < 0.4,
