diff --git a/Control/Failure.hs b/Control/Failure.hs
new file mode 100644
--- /dev/null
+++ b/Control/Failure.hs
@@ -0,0 +1,97 @@
+{-# LANGUAGE Rank2Types #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE FlexibleContexts #-}
+-- | Type classes for returning failures.
+module Control.Failure
+    ( -- * Type classes
+      Failure (..)
+    , FunctorFailure
+    , ApplicativeFailure
+    , MonadFailure
+      -- * Wrapping failures
+    , WrapFailure (..)
+      -- * Convenience 'String' failure
+    , StringException (..)
+    , failureString
+      -- * Convert 'Failure's into concrete types
+    , Try (..)
+    , NothingException (..)
+    , NullException (..)
+    ) where
+
+import Prelude hiding (catch)
+import Control.Exception (throw, catch, Exception, SomeException (..))
+import Data.Typeable (Typeable)
+import Control.Applicative (Applicative, pure)
+
+class Failure e f where
+    failure :: e -> f v
+class (Functor f, Failure e f) => FunctorFailure e f
+class (Applicative f, Failure e f) => ApplicativeFailure e f
+class (Monad f, Applicative f, Failure e f) => MonadFailure e f
+
+-- These introduce the need to use undecidables.
+-- However, since they are merely type class synonyms, this is acceptable.
+instance (Functor f, Failure e f) => FunctorFailure e f
+instance (Applicative f, Failure e f) => ApplicativeFailure e f
+instance (Monad f, Applicative f, Failure e f) => MonadFailure e f
+
+class Failure e f => WrapFailure e f 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) -> f a -> f a
+instance Exception e => WrapFailure e IO where
+    wrapFailure f m =
+        m `catch` \e@SomeException{} -> throw (f e)
+
+class Try f where
+  type Error f
+  -- Turn a concrete failure into an abstract failure
+  try :: ApplicativeFailure (Error f) f' => f a -> f' a
+
+-- | Call 'failure' with a 'String'.
+failureString :: Failure 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
+
+-- --------------
+-- base instances
+-- --------------
+
+instance Failure e Maybe where failure _ = Nothing
+instance Failure e []    where failure _ = []
+
+instance Exception e => Failure e IO where
+  failure = Control.Exception.throw
+
+instance Failure e (Either e) where failure = Left
+
+data NothingException = NothingException
+  deriving (Show, Typeable)
+instance Try Maybe where
+  type Error Maybe = NothingException
+  try Nothing      = failure NothingException
+  try (Just x)     = pure x
+
+instance Try (Either e) where
+  type Error (Either e) = e
+  try (Left  e)         = failure e
+  try (Right x)         = pure x
+
+data NullException = NullException
+  deriving (Show, Typeable)
+instance Try [] where
+  type Error [] = NullException
+  try []        = failure NullException
+  try (x:_)     = pure x
diff --git a/Setup.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,7 @@
+#!/usr/bin/env runhaskell
+
+> module Main where
+> import Distribution.Simple
+
+> main :: IO ()
+> main = defaultMain
diff --git a/failure.cabal b/failure.cabal
new file mode 100644
--- /dev/null
+++ b/failure.cabal
@@ -0,0 +1,24 @@
+name: failure
+version: 0.0.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/snoyberg/failure
+description: A simple type class for success/failure computations.
+synopsis: A simple type class for success/failure computations.
+category: Control, Monads, Failure
+stability: stable
+
+Library
+  buildable: True
+  build-depends: base >= 4 && < 5
+  ghc-options: -Wall
+
+  exposed-modules:
+     Control.Failure
+
+source-repository head
+  type:     git
+  location: git://github.com/snoyberg/failure.git
