module LIO.MonadCatch (MonadCatch(..), genericBracket) where
import Prelude hiding (catch)
import Control.Exception (Exception, SomeException)
import qualified Control.Exception as E
class (Monad m) => MonadCatch m where
block :: m a -> m a
unblock :: m a -> m a
throwIO :: (Exception e) => e -> m a
catch :: (Exception e) => m a -> (e -> m a) -> m a
handle :: (Exception e) => (e -> m a) -> m a -> m a
handle = flip catch
onException :: m a -> m b -> m a
onException io h = io `catch` \e -> h >> throwIO (e :: SomeException)
bracket :: m b -> (b -> m c) -> (b -> m a) -> m a
bracket = genericBracket onException
instance MonadCatch IO where
block = E.block
unblock = E.unblock
throwIO = E.throwIO
catch = E.catch
onException = E.onException
bracket = E.bracket
genericBracket :: (MonadCatch m) =>
(m b -> m c -> m b)
-> m a
-> (a -> m c)
-> (a -> m b)
-> m b
genericBracket myOnException before after between =
block $ do
a <- before
b <- unblock (between a) `myOnException` after a
after a >> return b