diff --git a/Control/Monad/Attempt.hs b/Control/Monad/Attempt.hs
--- a/Control/Monad/Attempt.hs
+++ b/Control/Monad/Attempt.hs
@@ -24,6 +24,7 @@
 import Control.Applicative
 import Control.Monad
 import Control.Monad.Trans
+import Control.Exception (Exception, SomeException (..))
 
 newtype AttemptT m v = AttemptT {
     runAttemptT :: m (Attempt v)
@@ -36,10 +37,14 @@
     (<*>) = ap
 instance Monad m => Monad (AttemptT m) where
     return = AttemptT . return . Success
-    (AttemptT mv) >>= f = AttemptT $
-        mv >>= attempt (return . Failure) (runAttemptT . f)
-instance Monad m => MonadAttempt (AttemptT m) where
-    failure = AttemptT . return . Failure
+    (AttemptT mv) >>= f = AttemptT $ do
+        v <- mv
+        case v of
+            Success v' -> runAttemptT $ f v'
+            Failure e -> return $ Failure e
+instance (Exception e, Monad m) => MonadFailure e (AttemptT m) where
+    failure = AttemptT . return . Failure . SomeException
+instance (Monad m, Exception e) => WrapFailure e (AttemptT m) where
     wrapFailure f (AttemptT mv) = AttemptT $ liftM (wrapFailure f) mv
 instance MonadTrans AttemptT where
     lift = AttemptT . liftM Success where
diff --git a/Control/Monad/Attempt/Class.hs b/Control/Monad/Attempt/Class.hs
deleted file mode 100644
--- a/Control/Monad/Attempt/Class.hs
+++ /dev/null
@@ -1,58 +0,0 @@
-{-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE Rank2Types #-}
----------------------------------------------------------
---
--- Module        : Control.Monad.Attempt.Class
--- Copyright     : Michael Snoyman
--- License       : BSD3
---
--- Maintainer    : Michael Snoyman <michael@snoyman.com>
--- Stability     : Unstable
--- Portability   : portable
---
----------------------------------------------------------
-
--- | Defines a type class for any monads which may report failure using
--- extensible exceptions.
-module Control.Monad.Attempt.Class
-    ( MonadAttempt (..)
-    , StringException (..)
-    ) where
-
-import Control.Exception
-import Data.Generics
-
--- | Any 'Monad' which may report failure using extensible exceptions. This
--- most obviously applies to the Attempt data type, but you should just as well
--- use this for arbitrary 'Monad's.
---
--- Usage should be straight forward: 'return' successes and 'failure' errors.
--- If you simply want to send a string error message, use 'failureString'.
--- Although tempting to do so, 'fail' is *not* used as a synonym for
--- 'failureString'; 'fail' should not be used at all.
---
--- Minimal complete definition: 'failure' and 'wrapFailure'.
-class Monad m => MonadAttempt m where
-    failure :: Exception e => e -> m v
-
-    -- | Call 'failure' by wrapping the argument in a 'StringException'.
-    failureString :: String -> m v
-    failureString = failure . StringException
-
-    -- | 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 :: Exception eOut
-                => (forall eIn. Exception eIn => eIn -> eOut)
-                -> m v
-                -> m v
-
--- | A simple exception which simply contains a string. Note that the 'Show'
--- instance simply returns the contained string.
-newtype StringException = StringException String
-    deriving Typeable
-instance Show StringException where
-    show (StringException s) = s
-instance Exception StringException
diff --git a/Data/Attempt.hs b/Data/Attempt.hs
--- a/Data/Attempt.hs
+++ b/Data/Attempt.hs
@@ -21,30 +21,39 @@
 -- you want this kind of functionality, something like control-monad-exception
 -- might be a more appropriate fit.
 module Data.Attempt
-    ( Attempt (..)
+    ( -- * Data type and type class
+      Attempt (..)
     , FromAttempt (..)
     , fa
+    , joinAttempt
+      -- * General handling of 'Attempt's
     , attempt
     , makeHandler
-    , AttemptHandler
-    , module Control.Monad.Attempt.Class
+    , AttemptHandler (..)
+      -- * Individual 'Attempt's
+    , isFailure
+    , isSuccess
+    , fromSuccess
+      -- * Lists of 'Attempt's
+    , successes
+    , failures
+    , partitionAttempts
+      -- * Reexport the 'MonadFailure' class
+    , module Control.Monad.Failure
     ) where
 
 import qualified Control.Exception as E
 import Control.Monad (ap)
 import Control.Applicative
 import Data.Generics
-import Control.Monad.Attempt.Class
+import Data.Either (lefts)
+import Control.Monad.Failure
 
 -- | Contains either a 'Success' value or a 'Failure' exception.
 data Attempt v =
     Success v
-    | forall e. E.Exception e => Failure e
-    deriving (Typeable)
-
-instance Show v => Show (Attempt v) where
-    show (Success v) = "Success " ++ show v
-    show (Failure e) = "Failure " ++ show e
+    | Failure E.SomeException
+    deriving (Show, Typeable)
 
 instance Functor Attempt where
     fmap f (Success v) = Success $ f v
@@ -56,10 +65,12 @@
     return = Success
     (Success v) >>= f = f v
     (Failure e) >>= _ = Failure e
-instance MonadAttempt Attempt where
-    failure = Failure
+instance E.Exception e => MonadFailure e Attempt where
+    failure = Failure . E.SomeException
+instance E.Exception e => WrapFailure e Attempt where
     wrapFailure _ (Success v) = Success v
-    wrapFailure f (Failure e) = Failure $ f e
+    wrapFailure f (Failure (E.SomeException e)) =
+        Failure $ E.SomeException $ f e
 
 -- | Any type which can be converted from an 'Attempt'. The included instances are your \"usual suspects\" for dealing with error handling. They include:
 --
@@ -93,6 +104,15 @@
 instance FromAttempt (Either E.SomeException) where
     fromAttempt = attempt (Left . E.SomeException) Right
 
+-- | This is not a simple translation of the Control.Monad.join function.
+-- Instead, for 'Monad's which are instances of 'FromAttempt', it removes the
+-- inner 'Attempt' type, reporting errors as defined in the 'FromAttempt'
+-- instance.
+--
+-- For example, join (Just (failureString \"foo\")) == Nothing.
+joinAttempt :: (FromAttempt m, Monad m) => m (Attempt v) -> m v
+joinAttempt = (>>= fromAttempt)
+
 -- | Process either the exception or value in an 'Attempt' to produce a result.
 --
 -- This function is modeled after 'maybe' and 'either'. The first argument must
@@ -121,3 +141,35 @@
 -- | A simple wrapper value necesary due to the Haskell type system. Wraps a
 -- function from a *specific* 'E.Exception' type to some value.
 data AttemptHandler v = forall e. E.Exception e => AttemptHandler (e -> v)
+
+
+-- | Tests for a 'Failure' value.
+isFailure :: Attempt v -> Bool
+isFailure = attempt (const True) (const False)
+
+-- | Tests for a 'Success' value.
+isSuccess :: Attempt v -> Bool
+isSuccess = attempt (const False) (const True)
+
+-- | This is an unsafe, partial function which should only be used if you
+-- either know that a function will succeed or don't mind the occassional
+-- runtime exception.
+fromSuccess :: Attempt v -> v
+fromSuccess = attempt (error . show) id
+
+-- | Returns only the 'Success' values.
+successes :: [Attempt v] -> [v]
+successes l = [ v | Success v <- l ]
+
+-- | Returns only the 'Failure' values, each wrapped in a 'SomeException'.
+failures :: [Attempt v] -> [E.SomeException]
+failures = lefts . map eitherExceptionFromAttempt where
+    eitherExceptionFromAttempt :: Attempt v -> Either E.SomeException v
+    eitherExceptionFromAttempt = fa
+
+-- | Return all of the 'Failure's and 'Success'es separately in a tuple.
+partitionAttempts :: [Attempt v] -> ([E.SomeException], [v])
+partitionAttempts = foldr (attempt f s) ([],[])
+ where
+  f a (l, r) = (E.SomeException a:l, r)
+  s a (l, r) = (l, a:r)
diff --git a/Data/Attempt/Helper.hs b/Data/Attempt/Helper.hs
deleted file mode 100644
--- a/Data/Attempt/Helper.hs
+++ /dev/null
@@ -1,132 +0,0 @@
-{-# LANGUAGE DeriveDataTypeable #-}
----------------------------------------------------------
---
--- Module        : Data.Attempt.Helper
--- Copyright     : Michael Snoyman
--- License       : BSD3
---
--- Maintainer    : Michael Snoyman <michael@snoyman.com>
--- Stability     : Unstable
--- Portability   : portable
----------------------------------------------------------
-
--- | Replacements for standard functions to represent failure with a
--- 'MonadAttempt'.  Lots of inspiration taken from the "safe" package.
-module Data.Attempt.Helper
-    ( -- * Non-standard functions
-      join
-      -- * Exception types
-    , KeyNotFound (..)
-    , EmptyList (..)
-    , CouldNotRead (..)
-    , NegativeIndex (..)
-      -- * Standard functions reimplemented
-    , lookup
-    , tail
-    , init
-    , head
-    , last
-    , read
-    , at
-    , assert
-      -- * IO functions with exceptions handled
-    , readFile
-    ) where
-
-import Prelude hiding (lookup, tail, init, head, last, read, readFile)
-import qualified Prelude
-import Data.Attempt
-import Control.Monad.Attempt.Class
-import Data.Generics
-import qualified Control.Exception as E
-import Control.Monad (liftM)
-import Control.Monad.Trans
-
--- | This is not a simple translation of the Control.Monad.join function.
--- Instead, for 'Monad's which are instances of 'FromAttempt', it removes the
--- inner 'Attempt' type, reporting errors as defined in the 'FromAttempt'
--- instance.
---
--- For example, join (Just (failureString \"foo\")) == Nothing.
-join :: (FromAttempt m, Monad m) => m (Attempt v) -> m v
-join = (>>= fromAttempt)
-
--- | Exception type for the 'lookup' function.
-data KeyNotFound k v = KeyNotFound k [(k, v)]
-    deriving Typeable
-instance Show k => Show (KeyNotFound k v) where
-    show (KeyNotFound key _) = "Could not find requested key: " ++ show key
-instance (Typeable k, Typeable v, Show k) => E.Exception (KeyNotFound k v)
-
-lookup :: (Typeable k, Typeable v, Show k, Eq k, MonadAttempt m)
-       => k
-       -> [(k, v)]
-       -> m v
-lookup k m = maybe (failure $ KeyNotFound k m) return $ Prelude.lookup k m
-
--- | Exception type for functions which expect non-empty lists.
-data EmptyList = EmptyList
-    deriving (Show, Typeable)
-instance E.Exception EmptyList
-
-tail :: MonadAttempt m => [a] -> m [a]
-tail [] = failure EmptyList
-tail (_:rest) = return rest
-
-init :: MonadAttempt m => [a] -> m [a]
-init [] = failure EmptyList
-init x = return $ Prelude.init x
-
-head :: MonadAttempt m => [a] -> m a
-head [] = failure EmptyList
-head (x:_) = return x
-
-last :: MonadAttempt m => [a] -> m a
-last [] = failure EmptyList
-last x = return $ Prelude.last x
-
--- | Report errors from the 'read' function.
-newtype CouldNotRead = CouldNotRead String
-    deriving (Typeable, Show)
-instance E.Exception CouldNotRead
-
-read :: (MonadAttempt m, Read a) => String -> m a
-read s = case [x | (x,t) <- reads s, ("","") <- lex t] of
-            [x] -> return x
-            _ -> failure $ CouldNotRead s
-
--- | For functions which expect index values >= 0.
-data NegativeIndex = NegativeIndex
-    deriving (Typeable, Show)
-instance E.Exception NegativeIndex
-data OutOfBoundsIndex = OutOfBoundsIndex
-    deriving (Typeable, Show)
-instance E.Exception OutOfBoundsIndex
-
--- | Same as Prelude.!!. Name stolen from safe library.
-at :: MonadAttempt m => [a] -> Int -> m a
-at [] _ = failure OutOfBoundsIndex
-at (x:_) 0 = return x
-at (_:xs) n
-    | n < 0 = failure NegativeIndex
-    | otherwise = at xs $ n - 1
-
--- | Assert a value to be true. If true, returns the first value as a succss.
--- Otherwise, returns the second value as a failure.
-assert :: (MonadAttempt m, E.Exception e)
-       => Bool
-       -> v
-       -> e
-       -> m v
-assert b v e = if b then return v else failure e
-
--- | The standard readFile function with any 'E.IOException's returned as a
--- failure instead of a runtime exception.
-readFile :: (MonadAttempt m, MonadIO m) => FilePath -> m String
-readFile fp = do
-    contents <- liftIO $ E.handle
-                    (\e -> return $ Left (e :: E.IOException))
-                    (liftM Right $ Prelude.readFile fp)
-    case contents of
-        Left e -> failure e
-        Right v -> return v
diff --git a/attempt.cabal b/attempt.cabal
--- a/attempt.cabal
+++ b/attempt.cabal
@@ -1,5 +1,5 @@
 name:            attempt
-version:         0.0.0
+version:         0.0.1
 license:         BSD3
 license-file:    LICENSE
 author:          Michael Snoyman <michael@snoyman.com>
@@ -15,9 +15,8 @@
 library
     build-depends:   base >= 4 && < 5,
                      syb,
-                     transformers >= 0.1.4.0
+                     transformers >= 0.1.4.0,
+                     control-monad-failure >= 0.2
     exposed-modules: Data.Attempt
-                     Data.Attempt.Helper
                      Control.Monad.Attempt
-                     Control.Monad.Attempt.Class
     ghc-options:     -Wall
