diff --git a/Control/Monad/Attempt.hs b/Control/Monad/Attempt.hs
--- a/Control/Monad/Attempt.hs
+++ b/Control/Monad/Attempt.hs
@@ -24,7 +24,8 @@
 import Control.Applicative
 import Control.Monad
 import Control.Monad.Trans
-import Control.Exception (Exception, SomeException (..))
+import Control.Monad.Loc
+import Control.Exception (Exception)
 
 newtype AttemptT m v = AttemptT {
     runAttemptT :: m (Attempt v)
@@ -36,22 +37,24 @@
     pure = return
     (<*>) = ap
 instance Monad m => Monad (AttemptT m) where
-    return = AttemptT . return . Success
+    return = AttemptT . return . return
     (AttemptT mv) >>= f = AttemptT $ do
         v <- mv
-        case v of
-            Success v' -> runAttemptT $ f v'
-            Failure e -> return $ Failure e
+        attempt (return . failure) (runAttemptT . f) v
 instance (Exception e, Monad m) => MonadFailure e (AttemptT m) where
-    failure = AttemptT . return . Failure . SomeException
+    failure = AttemptT . return . failure
 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
+    lift = AttemptT . liftM return where
 instance MonadIO m => MonadIO (AttemptT m) where
-    liftIO = AttemptT . liftM Success . liftIO where
+    liftIO = AttemptT . liftM return . liftIO where
 instance Monad m => FromAttempt (AttemptT m) where
     fromAttempt = attempt failure return
+instance MonadLoc m => MonadLoc (AttemptT m) where
+    withLoc loc (AttemptT a) = AttemptT $ do
+        current <- withLoc loc a
+        return $ withLoc loc current
 
 -- | Instances of 'FromAttempt' specify a manner for embedding 'Attempt'
 -- failures directly into the target data type. For example, the 'IO' instance
diff --git a/Data/Attempt.hs b/Data/Attempt.hs
--- a/Data/Attempt.hs
+++ b/Data/Attempt.hs
@@ -22,10 +22,11 @@
 -- might be a more appropriate fit.
 module Data.Attempt
     ( -- * Data type and type class
-      Attempt (..)
+      Attempt
     , FromAttempt (..)
     , fa
     , joinAttempt
+    , monadicStackTrace
       -- * General handling of 'Attempt's
     , attempt
     , makeHandler
@@ -48,29 +49,40 @@
 import Data.Generics
 import Data.Either (lefts)
 import Control.Monad.Failure
-
+import Control.Monad.Loc
+import GHC.Show (appPrec, appPrec1)
 -- | Contains either a 'Success' value or a 'Failure' exception.
-data Attempt v =
-    Success v
-    | Failure E.SomeException
-    deriving (Show, Typeable)
+data Attempt v
+  = Success v
+  | forall e. E.Exception e => Failure [String] e
+    deriving (Typeable)
 
+instance Show v => Show (Attempt v) where
+  showsPrec p (Success v)
+    = showParen (p > appPrec) $ showString "Success " . showsPrec appPrec1 v
+  showsPrec p (Failure st v)
+    = showParen (p > appPrec) $
+        showString "Failure " . showsPrec appPrec1 st . showString " "
+                              . showsPrec appPrec1 v
+
 instance Functor Attempt where
     fmap f (Success v) = Success $ f v
-    fmap _ (Failure e) = Failure e
+    fmap _ (Failure st e) = Failure st e
 instance Applicative Attempt where
     pure = Success
     (<*>) = ap
 instance Monad Attempt where
     return = Success
     (Success v) >>= f = f v
-    (Failure e) >>= _ = Failure e
+    (Failure st e) >>= _ = Failure st e
 instance E.Exception e => MonadFailure e Attempt where
-    failure = Failure . E.SomeException
+    failure = Failure []
 instance E.Exception e => WrapFailure e Attempt where
     wrapFailure _ (Success v) = Success v
-    wrapFailure f (Failure (E.SomeException e)) =
-        Failure $ E.SomeException $ f e
+    wrapFailure f (Failure st e) = Failure st $ f e
+instance MonadLoc Attempt where
+    withLoc _ (Success v) = Success v
+    withLoc s (Failure st e) = Failure (s:st) e
 
 -- | Any type which can be converted from an 'Attempt'. The included instances are your \"usual suspects\" for dealing with error handling. They include:
 --
@@ -102,7 +114,7 @@
 instance FromAttempt (Either String) where
     fromAttempt = attempt (Left . show) Right
 instance FromAttempt (Either E.SomeException) where
-    fromAttempt = attempt (Left . E.SomeException) Right
+    fromAttempt = attempt (Left . E.toException) 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
@@ -113,36 +125,48 @@
 joinAttempt :: (FromAttempt m, Monad m) => m (Attempt v) -> m v
 joinAttempt = (>>= fromAttempt)
 
+-- | Extra the monadic stack trace from the given 'Attempt' value. Returns the
+-- empty list when the given value is a 'Success'.
+monadicStackTrace :: Attempt a -> [String]
+monadicStackTrace (Success _) = []
+monadicStackTrace (Failure st _) = st
+
 -- | 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
 -- accept any instances of 'E.Exception'. If you want to handle multiple types
 -- of exceptions, see 'makeHandler'. The second argument converts the success
 -- value.
+--
+-- Note that this function does not expose all the data available in an
+-- 'Attempt' value. Notably, the monadic stack trace is not passed on to the
+-- error handler. If desired, use the 'monadicStackTrace' function to extract
+-- it.
 attempt :: (forall e. E.Exception e => e -> b) -- ^ error handler
         -> (a -> b) -- ^ success handler
         -> Attempt a
         -> b
 attempt _ f (Success v) = f v
-attempt f _ (Failure e) = f e
+attempt f _ (Failure _ e) = f e
 
 -- | Convert multiple 'AttemptHandler's and a default value into an exception
 -- handler.
 --
 -- This is a convenience function when you want to have special handling for a
 -- few types of 'E.Exception's and provide another value for anything else.
-makeHandler :: [AttemptHandler v] -> v -> (forall e. E.Exception e => e -> v)
+makeHandler :: [AttemptHandler v]
+            -> v
+            -> (forall e. E.Exception e => e -> v)
 makeHandler [] v _ = v
 makeHandler (AttemptHandler h:hs) v e =
-    case cast e of
-        Nothing -> makeHandler hs v e
+    case E.fromException (E.toException e) of
         Just e' -> h e'
+        Nothing -> makeHandler hs v e
 
 -- | 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)
@@ -171,5 +195,5 @@
 partitionAttempts :: [Attempt v] -> ([E.SomeException], [v])
 partitionAttempts = foldr (attempt f s) ([],[])
  where
-  f a (l, r) = (E.SomeException a:l, r)
+  f a (l, r) = (E.toException a:l, r)
   s a (l, r) = (l, a:r)
diff --git a/attempt.cabal b/attempt.cabal
--- a/attempt.cabal
+++ b/attempt.cabal
@@ -1,8 +1,8 @@
 name:            attempt
-version:         0.0.1
+version:         0.0.2
 license:         BSD3
 license-file:    LICENSE
-author:          Michael Snoyman <michael@snoyman.com>
+author:          Michael Snoyman, Nicolas Pouillard
 maintainer:      Michael Snoyman <michael@snoyman.com>
 synopsis:        Error handling using extensible exceptions outside the IO monad.
 description:     Defines a data type, Attempt, which has a Success and Failure constructor. Failure contains an extensible exception.
@@ -16,7 +16,8 @@
     build-depends:   base >= 4 && < 5,
                      syb,
                      transformers >= 0.1.4.0,
-                     control-monad-failure >= 0.2
+                     control-monad-failure >= 0.4,
+                     monadloc >= 0.4
     exposed-modules: Data.Attempt
                      Control.Monad.Attempt
     ghc-options:     -Wall
