#if MIN_VERSION_exceptions(0,9,0)
module Control.Monad.Trans.Except.Exception (
bracket
, bracket_
, bracketOnError
) where
import Control.Monad.Catch (MonadMask)
import qualified Control.Monad.Catch as Ex
import Control.Monad.Trans.Except (ExceptT)
bracket ::
MonadMask m
=> ExceptT e m a
-> (a -> ExceptT e m c)
-> (a -> ExceptT e m b)
-> ExceptT e m b
bracket =
Ex.bracket
bracket_ ::
MonadMask m
=> ExceptT e m a
-> ExceptT e m b
-> ExceptT e m c
-> ExceptT e m c
bracket_ =
Ex.bracket_
bracketOnError ::
MonadMask m
=> ExceptT e m a
-> (a -> ExceptT e m c)
-> (a -> ExceptT e m b)
-> ExceptT e m b
bracketOnError =
Ex.bracketOnError
#else
module Control.Monad.Trans.Except.Exception (
bracket
, bracket_
, bracketOnError
) where
import Control.Exception (SomeException)
import Control.Monad (Monad (..), liftM)
import Control.Monad.Catch (MonadMask (..), catchAll, throwM)
import Control.Monad.Trans.Except (ExceptT (..), runExceptT)
import Data.Either (Either (..), either)
import Data.Function (($), (.), const, id)
bracket ::
MonadMask m
=> ExceptT e m a
-> (a -> ExceptT e m c)
-> (a -> ExceptT e m b)
-> ExceptT e m b
bracket acquire release run =
ExceptT $ bracketF
(runExceptT acquire)
(\r -> case r of
Left _ ->
return . Right $ ()
Right r' ->
runExceptT (release r') >>= \x -> return $ case x of
Left err -> Left (Left err)
Right _ -> Right ())
(\r -> case r of
Left err ->
return . Left $ err
Right r' ->
runExceptT (run r'))
bracket_ ::
MonadMask m
=> ExceptT e m a
-> ExceptT e m b
-> ExceptT e m c
-> ExceptT e m c
bracket_ acquire release run =
bracket acquire (const release) (const run)
bracketOnError ::
MonadMask m
=> ExceptT e m a
-> (a -> ExceptT e m c)
-> (a -> ExceptT e m b)
-> ExceptT e m b
bracketOnError acquire release run =
ExceptT $ bracketOnErrorF
(runExceptT acquire)
(\r -> case r of
Left _ ->
return . Right $ ()
Right r' ->
runExceptT (release r') >>= \x -> return $ case x of
Left err -> Left (Left err)
Right _ -> Right ())
(\r -> case r of
Left err ->
return . Left $ err
Right r' ->
runExceptT (run r'))
data BracketResult a =
BracketOk a
| BracketFailedFinalizerOk SomeException
| BracketFailedFinalizerError a
bracketF :: MonadMask m => m a -> (a -> m (Either b c)) -> (a -> m b) -> m b
bracketF a f g =
mask $ \restore -> do
a' <- a
x <- restore (BracketOk `liftM` g a') `catchAll`
(\ex -> either BracketFailedFinalizerError (const $ BracketFailedFinalizerOk ex) `liftM` f a')
case x of
BracketFailedFinalizerOk ex ->
throwM ex
BracketFailedFinalizerError b ->
return b
BracketOk b -> do
z <- f a'
return $ either id (const b) z
bracketOnErrorF :: MonadMask m => m a -> (a -> m (Either b c)) -> (a -> m b) -> m b
bracketOnErrorF a f g =
mask $ \restore -> do
a' <- a
x <- restore (BracketOk `liftM` g a') `catchAll`
(\ex -> either BracketFailedFinalizerError (const $ BracketFailedFinalizerOk ex) `liftM` f a')
case x of
BracketFailedFinalizerOk ex ->
throwM ex
BracketFailedFinalizerError b ->
return b
BracketOk b -> do
return b
#endif