FailureT-15321.1: Control/Monad/Failure.hs
module Control.Monad.Failure (module Control.Monad.Failure.Class, FailureT (..)) where
import Prelude hiding (fail);
import Control.Monad hiding (fail);
import Control.Monad.Fix;
import Control.Monad.Trans;
import Control.Monad.Failure.Class;
import Data.Traversable;
newtype FailureT f m a = FailureT { runFailureT :: m (Either f a) };
mapFailureT :: (m (Either f a) -> n (Either f b)) -> FailureT f m a -> FailureT f n b;
mapFailureT f = FailureT . f . runFailureT;
instance MonadTrans (FailureT f) where {
lift = FailureT . liftM Right;
tmap f _ = mapFailureT f;
};
instance Functor m => Functor (FailureT f m) where {
fmap = mapFailureT . fmap . fmap;
};
instance Monad m => Monad (FailureT f m) where {
return = lift . return;
FailureT x >>= f = FailureT $ x >>= liftM join . either (liftM Left . return) (liftM Right . runFailureT . f);
};
instance MonadFix m => MonadFix (FailureT f m) where {
mfix f = FailureT $ mfix (either (return . Left) (runFailureT . f));
};
instance (Monad m, MonadTrans xT, Monad (xT (FailureT f m))) => MonadFailure f (xT (FailureT f m)) where {
fail = lift . fail;
};
instance Monad m => MonadFailure f (FailureT f m) where {
fail = FailureT . return . Left;
};
instance Monad m => MonadSalvage f (FailureT f m) where {
save f = mapFailureT (>>= runFailureT . either f return);
};