packages feed

exception-transformers 0.2 → 0.3

raw patch · 3 files changed

+210/−47 lines, 3 filesdep ~basedep ~stmPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: base, stm

API changes (from Hackage documentation)

- Control.Monad.Exception: block :: MonadAsyncException m => m a -> m a
- Control.Monad.Exception: instance Monad m => Functor (ExceptionT m)
- Control.Monad.Exception: unblock :: MonadAsyncException m => m a -> m a
+ Control.Monad.Exception: bracket :: MonadAsyncException m => m a -> (a -> m b) -> (a -> m c) -> m c
+ Control.Monad.Exception: bracket_ :: MonadAsyncException m => m a -> m b -> m c -> m c
+ Control.Monad.Exception: finally :: MonadException m => m a -> m b -> m a
+ Control.Monad.Exception: instance (Functor m, Monad m) => Alternative (ExceptionT m)
+ Control.Monad.Exception: instance (Functor m, Monad m) => Applicative (ExceptionT m)
+ Control.Monad.Exception: instance (MonadAsyncException m, Error e) => MonadAsyncException (ErrorT e m)
+ Control.Monad.Exception: instance (MonadException m, Error e) => MonadException (ErrorT e m)
+ Control.Monad.Exception: instance Functor m => Functor (ExceptionT m)
+ Control.Monad.Exception: instance MonadAsyncException m => MonadAsyncException (IdentityT m)
+ Control.Monad.Exception: instance MonadAsyncException m => MonadAsyncException (ListT m)
+ Control.Monad.Exception: instance MonadAsyncException m => MonadAsyncException (MaybeT m)
+ Control.Monad.Exception: instance MonadException m => MonadException (IdentityT m)
+ Control.Monad.Exception: instance MonadException m => MonadException (ListT m)
+ Control.Monad.Exception: instance MonadException m => MonadException (MaybeT m)
+ Control.Monad.Exception: mask :: MonadAsyncException m => ((forall a. m a -> m a) -> m b) -> m b
+ Control.Monad.Exception: onException :: MonadException m => m a -> m b -> m a

Files

Control/Monad/Exception.hs view
@@ -1,4 +1,4 @@--- Copyright (c) 2008-2010+-- Copyright (c) 2008-2011 --         The President and Fellows of Harvard College. -- -- Redistribution and use in source and binary forms, with or without@@ -28,13 +28,15 @@ -------------------------------------------------------------------------------- -- | -- Module      :  Control.Monad.Exception--- Copyright   :  (c) Harvard University 2008-2010+-- Copyright   :  (c) Harvard University 2008-2011 -- License     :  BSD-style -- Maintainer  :  mainland@eecs.harvard.edu -- -------------------------------------------------------------------------------- +{-# LANGUAGE CPP #-} {-# LANGUAGE MagicHash #-}+{-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE UnboxedTuples #-} @@ -43,7 +45,11 @@     E.SomeException,      MonadException(..),+    onException,+     MonadAsyncException(..),+    bracket,+    bracket_,      ExceptionT(..),     mapExceptionT,@@ -52,50 +58,139 @@  import Prelude hiding (catch) +import Control.Applicative import qualified Control.Exception as E (Exception(..),                                          SomeException,-                                         block,                                          catch,                                          throw,+                                         finally)+#if __GLASGOW_HASKELL__ >= 700+import qualified Control.Exception as E (mask)+#else /* __GLASGOW_HASKELL__ < 700 */+import qualified Control.Exception as E (block,+                                         blocked,                                          unblock)+#endif /* __GLASGOW_HASKELL__ < 700 */ import Control.Monad (MonadPlus(..)) import Control.Monad.Fix (MonadFix(..)) import Control.Monad.IO.Class (MonadIO(..)) import Control.Monad.Trans.Class (MonadTrans(..))+import Control.Monad.Trans.Error (Error(..),+                                  ErrorT(..),+                                  mapErrorT,+                                  runErrorT)+import Control.Monad.Trans.Identity (IdentityT(..),+                                     mapIdentityT,+                                     runIdentityT)+import Control.Monad.Trans.List (ListT(..),+                                 mapListT,+                                 runListT)+import Control.Monad.Trans.Maybe (MaybeT(..),+                                  mapMaybeT,+                                  runMaybeT) import Control.Monad.Trans.RWS.Lazy as Lazy (RWST(..),+                                             mapRWST,                                              runRWST) import Control.Monad.Trans.RWS.Strict as Strict (RWST(..),+                                                 mapRWST,                                                  runRWST)-import Control.Monad.Trans.Reader (ReaderT(..))+import Control.Monad.Trans.Reader (ReaderT(..),+                                   mapReaderT) import Control.Monad.Trans.State.Lazy as Lazy (StateT(..),+                                               mapStateT,                                                runStateT) import Control.Monad.Trans.State.Strict as Strict (StateT(..),+                                                   mapStateT,                                                    runStateT) import Control.Monad.Trans.Writer.Lazy as Lazy (WriterT(..),+                                                mapWriterT,                                                 runWriterT) import Control.Monad.Trans.Writer.Strict as Strict (WriterT(..),+                                                    mapWriterT,                                                     runWriterT) import Data.Monoid (Monoid)+#if __GLASGOW_HASKELL__ >= 700+import GHC.Conc.Sync (STM(..),+                      catchSTM,+                      throwSTM)+#else /* __GLASGOW_HASKELL__ < 700 */ import GHC.Base (RealWorld,                  State#,                  catchSTM#,                  raiseIO#) import GHC.Conc (STM(..))+#endif /* __GLASGOW_HASKELL__ < 700 */  class (Monad m) => MonadException m where-    -- |Throw an exception.+    -- | Throw an exception.     throw :: E.Exception e => e -> m a-    -- |Catch an exception.-    catch :: E.Exception e => m a -> (e -> m a) -> m a+    -- | Catch an exception.+    catch :: E.Exception e+          => m a        -- ^ The computation to run+          -> (e -> m a) -- ^ Handler to invoke if an exception is raised+          -> m a+    -- | Run a computation and always perform a second, final computation even+    -- if an exception is raised. If a short-circuiting monad transformer such+    -- as ErrorT or MaybeT is used to transform a MonadException monad, then the+    -- implementation of @finally@ for the transformed monad must guarantee that+    -- the final action is also always performed when any short-circuiting+    -- occurs.+    finally :: m a  -- ^ The computation to run+            -> m b  -- ^ Computation to run afterward (even if an exception was+                    -- raised)+            -> m a+    act `finally` sequel = do+        a <- act `catch` \(e :: E.SomeException) -> sequel >> throw e+        _ <- sequel+        return a +-- | If an exception is raised by the computation, then perform a final action+-- and re-raise the exception. If a short-circuiting monad transformer such as+-- ErrorT or MaybeT is used to transform a MonadException monad, then the+-- onException implementation for the transformer must guarantee that the final+-- action is also performed when any short-circuiting occurs.+onException :: MonadException m+            => m a -- ^ The computation to run+            -> m b -- ^ Computation to run if an exception is raised+            -> m a+onException act what =+    act `catch` \(e :: E.SomeException) -> what >> throw e+ class (MonadIO m, MonadException m) => MonadAsyncException m where-    -- |Applying 'block' to a computation will execute that computation with-    -- asynchronous exceptions /blocked/.-    block :: m a -> m a-    -- |To re-enable asynchronous exceptions inside the scope of 'block',-    -- 'unblock' can be used.-    unblock :: m a -> m a+    -- | Executes a computation with asynchronous exceptions /masked/. The+    -- argument passed to 'mask' is a function that takes as its argument+    -- another function, which can be used to restore the prevailing masking+    -- state within the context of the masked computation.+    mask :: ((forall a. m a -> m a) -> m b) -> m b +-- | When you want to acquire a resource, do some work with it, and then release+-- the resource, it is a good idea to use 'bracket', because 'bracket' will+-- install the necessary exception handler to release the resource in the event+-- that an exception is raised during the computation.  If an exception is+-- raised, then 'bracket' will re-raise the exception (after performing the+-- release).+bracket :: MonadAsyncException m+        => m a         -- ^ computation to run first (\"acquire resource\")+        -> (a -> m b)  -- ^ computation to run last (\"release resource\")+        -> (a -> m c)  -- ^ computation to run in-between+        -> m c         -- returns the value from the in-between computation+bracket before after thing =+    mask $ \restore -> do+        a <- before+        r <- restore (thing a) `onException` after a+        _ <- after a+        return r++-- | A variant of 'bracket' where the return value from the first computation is+-- not required.+bracket_ :: MonadAsyncException m+         => m a+         -> m b+         -> m c+         -> m c+bracket_ before after thing =+    bracket before (const after) (const thing)+ -- -- The ExceptionT monad transformer. --@@ -106,9 +201,9 @@ mapExceptionT :: (m (Either E.SomeException a) -> n (Either E.SomeException b))               -> ExceptionT m a               -> ExceptionT n b-mapExceptionT f m = ExceptionT $ f (runExceptionT m)+mapExceptionT f = ExceptionT . f . runExceptionT --- |Lift the result of running a computation in a monad transformed by+-- | Lift the result of running a computation in a monad transformed by -- 'ExceptionT' into another monad that supports exceptions. liftException :: MonadException m => Either E.SomeException a -> m a liftException (Left e)  = throw e@@ -119,12 +214,8 @@         a <- m         return (Right a) -instance (Monad m) => Functor (ExceptionT m) where-    fmap f m = ExceptionT $ do-        a <- runExceptionT m-        case a of-            Left  l -> return (Left  l)-            Right r -> return (Right (f r))+instance (Functor m) => Functor (ExceptionT m) where+    fmap f = ExceptionT . fmap (fmap f) . runExceptionT  instance (Monad m) => Monad (ExceptionT m) where     return a = ExceptionT $ return (Right a)@@ -143,6 +234,22 @@           Left _  -> runExceptionT n           Right r -> return (Right r) +instance (Functor m, Monad m) => Applicative (ExceptionT m) where+    pure a  = ExceptionT $ return (Right a)+    f <*> v = ExceptionT $ do+        mf <- runExceptionT f+        case mf of+            Left  e -> return (Left e)+            Right k -> do+                mv <- runExceptionT v+                case mv of+                    Left  e -> return (Left e)+                    Right x -> return (Right (k x))++instance (Functor m, Monad m) => Alternative (ExceptionT m) where+    empty = mzero+    (<|>) = mplus+ instance (MonadFix m) => MonadFix (ExceptionT m) where     mfix f = ExceptionT $ mfix $ \a -> runExceptionT $ f $ case a of         Right r -> r@@ -160,24 +267,32 @@  instance (MonadIO m) => MonadIO (ExceptionT m) where     liftIO m = ExceptionT $ liftIO $-        (m >>= return . Right)-        `E.catch` \(e :: E.SomeException) -> return (Left e)+        fmap Right m `E.catch` \(e :: E.SomeException) -> return (Left e)  instance (MonadAsyncException m) => MonadAsyncException (ExceptionT m) where-    block   = ExceptionT . block . runExceptionT-    unblock = ExceptionT . unblock . runExceptionT+    mask act = ExceptionT $ mask $ \restore ->+               runExceptionT $ act (mapExceptionT restore)  -- -- Instances for the IO monad. --  instance MonadException IO where-    catch = E.catch-    throw = E.throw+    catch   = E.catch+    throw   = E.throw+    finally = E.finally +#if __GLASGOW_HASKELL__ >= 700 instance MonadAsyncException IO where-    block   = E.block-    unblock = E.unblock+    mask = E.mask+#else /* __GLASGOW_HASKELL__ < 700 */+instance MonadAsyncException IO where+    mask act = do+        b <- E.blocked+        if b+          then act id+          else E.block $ act E.unblock+#endif /* __GLASGOW_HASKELL__ < 700 */  -- -- Instances for the STM monad.@@ -187,6 +302,7 @@     catch = catchSTM     throw = throwSTM +#if __GLASGOW_HASKELL__ < 700 unSTM :: STM a -> (State# RealWorld -> (# State# RealWorld, a #)) unSTM (STM a) = a @@ -199,11 +315,38 @@  throwSTM :: E.Exception e => e -> STM a throwSTM e = STM $ raiseIO# (E.toException e)+#endif /* __GLASGOW_HASKELL__ < 700 */  -- -- MonadException instances for transformers. -- +instance (MonadException m, Error e) =>+    MonadException (ErrorT e m) where+    throw       = lift . throw+    m `catch` h = mapErrorT (\m' -> m' `catch` \e -> runErrorT (h e)) m++    act `finally` sequel =+        mapErrorT (\act' -> act' `finally` runErrorT sequel) act++instance (MonadException m) =>+    MonadException (IdentityT m) where+    throw       = lift . throw+    m `catch` h = mapIdentityT (\m' -> m' `catch` \e -> runIdentityT (h e)) m++instance MonadException m =>+    MonadException (ListT m) where+    throw       = lift . throw+    m `catch` h = mapListT (\m' -> m' `catch` \e -> runListT (h e)) m++instance (MonadException m) =>+    MonadException (MaybeT m) where+    throw       = lift . throw+    m `catch` h = mapMaybeT (\m' -> m' `catch` \e -> runMaybeT (h e)) m++    act `finally` sequel =+        mapMaybeT (\act' -> act' `finally` runMaybeT sequel) act+ instance (Monoid w, MonadException m) =>     MonadException (Lazy.RWST r w s m) where     throw       = lift . throw@@ -250,37 +393,57 @@ -- MonadAsyncException instances for transformers. -- +instance (MonadAsyncException m, Error e) =>+    MonadAsyncException (ErrorT e m) where+    mask act = ErrorT $ mask $ \restore ->+               runErrorT $ act (mapErrorT restore)++instance (MonadAsyncException m) =>+    MonadAsyncException (IdentityT m) where+    mask act = IdentityT $ mask $ \restore ->+               runIdentityT $ act (mapIdentityT restore)++instance (MonadAsyncException m) =>+    MonadAsyncException (ListT m) where+    mask act = ListT $ mask $ \restore ->+               runListT $ act (mapListT restore)++instance (MonadAsyncException m) =>+    MonadAsyncException (MaybeT m) where+    mask act = MaybeT $ mask $ \restore ->+               runMaybeT $ act (mapMaybeT restore)+ instance (Monoid w, MonadAsyncException m) =>     MonadAsyncException (Lazy.RWST r w s m) where-    block m    = Lazy.RWST $ \r s -> block (Lazy.runRWST m r s)-    unblock m  = Lazy.RWST $ \r s -> unblock (Lazy.runRWST m r s)+    mask act = Lazy.RWST $ \r s -> mask $ \restore ->+               Lazy.runRWST (act (Lazy.mapRWST restore)) r s  instance (Monoid w, MonadAsyncException m) =>     MonadAsyncException (Strict.RWST r w s m) where-    block m    = Strict.RWST $ \r s -> block (Strict.runRWST m r s)-    unblock m  = Strict.RWST $ \r s -> unblock (Strict.runRWST m r s)+    mask act = Strict.RWST $ \r s -> mask $ \restore ->+               Strict.runRWST (act (Strict.mapRWST restore)) r s  instance (MonadAsyncException m) =>     MonadAsyncException (ReaderT r m) where-    block m    = ReaderT $ \r -> block (runReaderT m r)-    unblock m  = ReaderT $ \r -> unblock (runReaderT m r)+    mask act = ReaderT $ \r -> mask $ \restore ->+               runReaderT (act (mapReaderT restore)) r  instance (MonadAsyncException m) =>     MonadAsyncException (Lazy.StateT s m) where-    block m    = Lazy.StateT $ \s -> block (Lazy.runStateT m s)-    unblock m  = Lazy.StateT $ \s -> unblock (Lazy.runStateT m s)+    mask act = Lazy.StateT $ \s -> mask $ \restore ->+               Lazy.runStateT (act (Lazy.mapStateT restore)) s  instance (MonadAsyncException m) =>     MonadAsyncException (Strict.StateT s m) where-    block m    = Strict.StateT $ \s -> block (Strict.runStateT m s)-    unblock m  = Strict.StateT $ \s -> unblock (Strict.runStateT m s)+    mask act = Strict.StateT $ \s -> mask $ \restore ->+               Strict.runStateT (act (Strict.mapStateT restore)) s  instance (Monoid w, MonadAsyncException m) =>     MonadAsyncException (Lazy.WriterT w m) where-    block m    = Lazy.WriterT $ block (Lazy.runWriterT m)-    unblock m  = Lazy.WriterT $ unblock (Lazy.runWriterT m)+    mask act = Lazy.WriterT $ mask $ \restore ->+               Lazy.runWriterT $ act (Lazy.mapWriterT restore)  instance (Monoid w, MonadAsyncException m) =>     MonadAsyncException (Strict.WriterT w m) where-    block m    = Strict.WriterT $ block (Strict.runWriterT m)-    unblock m  = Strict.WriterT $ unblock (Strict.runWriterT m)+    mask act = Strict.WriterT $ mask $ \restore ->+               Strict.runWriterT $ act (Strict.mapWriterT restore)
LICENSE view
@@ -1,4 +1,4 @@-Copyright (c) 2008-2010+Copyright (c) 2008-2011         The President and Fellows of Harvard College.  Redistribution and use in source and binary forms, with or without
exception-transformers.cabal view
@@ -1,9 +1,9 @@ name:           exception-transformers-version:        0.2+version:        0.3 cabal-version:  >= 1.6 license:        BSD3 license-file:   LICENSE-copyright:      (c) 2008-2010 Harvard University+copyright:      (c) 2008-2011 Harvard University author:         Geoffrey Mainland <mainland@eecs.harvard.edu> maintainer:     mainland@eecs.harvard.edu stability:      alpha@@ -23,7 +23,7 @@    build-depends:     base >=4 && <5,-    stm >=2.1 && <2.2,+    stm >=2.1 && <2.3,     transformers >=0.2 && <0.3    ghc-options: