diff --git a/Control/Monad/Failure.hs b/Control/Monad/Failure.hs
new file mode 100644
--- /dev/null
+++ b/Control/Monad/Failure.hs
@@ -0,0 +1,3 @@
+module Control.Monad.Failure (module Control.Monad.Failure.Class) where
+
+import Control.Monad.Failure.Class
diff --git a/Control/Monad/Failure/Class.hs b/Control/Monad/Failure/Class.hs
new file mode 100644
--- /dev/null
+++ b/Control/Monad/Failure/Class.hs
@@ -0,0 +1,39 @@
+{-# LANGUAGE Rank2Types #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-| Defines the class @MonadFailure@ for monads which can fail.
+-}
+module Control.Monad.Failure.Class where
+
+import Control.Exception (throw, Exception)
+import Data.Typeable
+
+class Monad m => MonadFailure e m where
+    failure :: e -> m a
+
+class MonadFailure e m => WrapFailure e m where
+    -- | Wrap the failure value, if any, with the given function. This is
+    -- useful in particular when you want all the exceptions returned from a
+    -- certain library to be of a certain type, even if they were generated by
+    -- a different library.
+    wrapFailure :: (forall eIn. Exception eIn => eIn -> e) -> m a -> m a
+
+-- --------------
+-- base instances
+-- --------------
+
+instance MonadFailure e Maybe where failure _ = Nothing
+instance MonadFailure e []    where failure _ = []
+
+instance Exception e => MonadFailure e IO where
+  failure = Control.Exception.throw
+
+-- | Call 'failure' with a 'String'.
+failureString :: MonadFailure StringException m => String -> m a
+failureString = failure . StringException
+
+newtype StringException = StringException String
+    deriving Typeable
+instance Show StringException where
+    show (StringException s) = "StringException: " ++ s
+instance Exception StringException
diff --git a/Control/Monad/Failure/MTL.hs b/Control/Monad/Failure/MTL.hs
new file mode 100644
--- /dev/null
+++ b/Control/Monad/Failure/MTL.hs
@@ -0,0 +1,80 @@
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+
+module Control.Monad.Failure.MTL (module Control.Monad.Failure.Class) where
+
+import Control.Monad.Failure.Class
+
+import Control.Monad.Error
+import Control.Monad.List
+import Control.Monad.Reader
+import Control.Monad.State.Lazy     as Lazy
+import Control.Monad.State.Strict   as Strict
+import Control.Monad.Writer.Lazy    as Lazy
+import Control.Monad.Writer.Strict  as Strict
+import Control.Monad.RWS.Lazy       as Lazy
+import Control.Monad.RWS.Strict     as Strict
+import Data.Monoid
+
+-- -----------------------
+-- MonadFailure Instances
+-- -----------------------
+
+instance (Error e) => MonadFailure e (Either e) where
+  failure = Left
+
+instance (Error e, Monad m) => MonadFailure e (ErrorT e m) where
+  failure = throwError
+
+instance MonadFailure e m => MonadFailure e (ListT m) where
+  failure = lift . failure
+
+instance MonadFailure e m => MonadFailure e (ReaderT r m) where
+  failure = lift . failure
+
+instance (Monoid w, MonadFailure e m) => MonadFailure e (Lazy.WriterT w  m) where
+  failure = lift . failure
+
+instance MonadFailure e m => MonadFailure e (Lazy.StateT s m) where
+  failure = lift . failure
+
+instance (Monoid w, MonadFailure e m) => MonadFailure e (Lazy.RWST r w s m) where
+  failure = lift . failure
+
+instance (Monoid w, MonadFailure e m) => MonadFailure e (Strict.WriterT w  m) where
+  failure = lift . failure
+
+instance MonadFailure e m => MonadFailure e (Strict.StateT s m) where
+  failure = lift . failure
+
+instance (Monoid w, MonadFailure e m) => MonadFailure e (Strict.RWST r w s m) where
+  failure = lift . failure
+
+-- ---------------------
+-- WrapFailure instances
+-- ---------------------
+
+instance WrapFailure e m => WrapFailure e (ListT m) where
+  wrapFailure f = ListT . wrapFailure f . runListT
+
+instance WrapFailure e m => WrapFailure e (ReaderT r m) where
+  wrapFailure f m = ReaderT $ \r -> wrapFailure f (runReaderT m r)
+
+instance (WrapFailure e m, Monoid w) => WrapFailure e (Lazy.WriterT w m) where
+  wrapFailure f = Lazy.WriterT . wrapFailure f . Lazy.runWriterT
+
+
+-- all the following instances require undecidable instances
+instance WrapFailure e m => WrapFailure e (Lazy.StateT s m) where
+  wrapFailure f m = Lazy.StateT $ \s -> wrapFailure f (Lazy.runStateT m s)
+
+instance (WrapFailure e m, Monoid w) => WrapFailure e (Lazy.RWST r w s m) where
+  wrapFailure f m = Lazy.RWST $ \r s -> wrapFailure f (Lazy.runRWST m r s)
+
+instance WrapFailure e m => WrapFailure e (Strict.StateT s m) where
+  wrapFailure f m = Strict.StateT $ \s -> wrapFailure f (Strict.runStateT m s)
+
+instance (WrapFailure e m, Monoid w) => WrapFailure e (Strict.RWST r w s m) where
+  wrapFailure f m = Strict.RWST $ \r s -> wrapFailure f (Strict.runRWST m r s)
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/control-monad-failure-mtl.cabal b/control-monad-failure-mtl.cabal
new file mode 100644
--- /dev/null
+++ b/control-monad-failure-mtl.cabal
@@ -0,0 +1,26 @@
+name: control-monad-failure-mtl
+version: 0.5.0
+Cabal-Version:  >= 1.6
+build-type: Simple
+license: PublicDomain
+author: Pepe Iborra, Michael Snoyman, Nicolas Pouillard
+maintainer: pepeiborra@gmail.com
+homepage: http://github.com/pepeiborra/control-monad-failure
+description: A class for monads which can fail with an error.
+synopsis: A class for monads which can fail with an error.
+category: Control, Monads
+stability: experimental
+
+Library
+  buildable: True
+  build-depends: base >= 4 && < 5, mtl
+  ghc-options: -Wall
+  extensions:  MultiParamTypeClasses, FlexibleInstances
+  exposed-modules:
+     Control.Monad.Failure
+     Control.Monad.Failure.Class
+     Control.Monad.Failure.MTL
+
+source-repository head
+  type:     git
+  location: git://github.com/pepeiborra/control-monad-failure.git
