module Network.Monad.Exception where
import qualified Control.Monad.Exception.Asynchronous as Async
import qualified Control.Monad.Exception.Synchronous as Sync
import Control.Applicative (WrappedMonad(WrapMonad), unwrapMonad, )
import Control.Monad (liftM, )
import Data.Monoid (Monoid, mappend, )
import Prelude hiding (map, )
type AsyncExceptionalT e m a = m (Async.Exceptional e a)
map ::
(Monad m) =>
(a -> b) ->
Async.ExceptionalT body m a -> Async.ExceptionalT body m b
map f =
Async.mapExceptionalT unwrapMonad .
fmap f .
Async.mapExceptionalT WrapMonad
infixr 1 `bind`, `append`, `continue`
bind :: (Monad m, Monoid b) =>
Sync.ExceptionalT e m a -> (a -> AsyncExceptionalT e m b) -> AsyncExceptionalT e m b
bind x y =
Sync.tryT x >>= \result ->
liftM Async.force
(case result of
Sync.Exception e -> return $ Async.throwMonoid e
Sync.Success s -> y s)
append :: (Monad m, Monoid a) => Sync.ExceptionalT e m a -> AsyncExceptionalT e m a -> AsyncExceptionalT e m a
append x y =
bind x (\s -> liftM (fmap (mappend s)) y)
continue :: (Monad m, Monoid a) => Sync.ExceptionalT e m () -> AsyncExceptionalT e m a -> AsyncExceptionalT e m a
continue x y =
bind x (\_s -> y)
switch :: Async.Exceptional e a -> (a -> b) -> (a -> Async.Exceptional e b) -> Async.Exceptional e b
switch ea@(Async.Exceptional mea a) exception success =
case mea of
Just _ -> fmap exception ea
Nothing -> success a
switchM :: (Monad m) => m (Async.Exceptional e a) -> (a -> m b) -> (a -> m (Async.Exceptional e b)) -> m (Async.Exceptional e b)
switchM actA exception success =
do ea@(Async.Exceptional mea a) <- actA
case mea of
Just _ -> Async.mapM exception ea
Nothing -> success a