module Control.Monad.Trans.Result
( ResultT, runResultT, hoist
, raiseT, raiseAllT
, accumulateT, accumulateT_
, fromExceptT
) where
import Control.Applicative (liftA2)
import Control.Monad (join)
import Control.Monad.Trans.Class
import Control.Monad.Trans.Except
import qualified Control.Monad.State.Class as State
import Data.Functor.Identity
import Data.Result
data ResultT e m a = ResultT { runResultT :: m (Result e a) }
instance Functor f => Functor (ResultT e f) where
fmap f (ResultT m) =
ResultT (fmap (fmap f) m)
instance Applicative f => Applicative (ResultT e f) where
pure a =
ResultT (pure (pure a))
(ResultT mf) <*> (ResultT ma) =
ResultT $
liftA2 (<*>) mf ma
instance Monad m => Monad (ResultT e m) where
return =
pure
(ResultT m) >>= f =
ResultT $
m >>= fmap join . traverse (runResultT . f)
instance MonadTrans (ResultT e) where
lift m =
ResultT (pure <$> m)
hoist :: Applicative f => Result e a -> ResultT e f a
hoist r =
ResultT (pure r)
raiseT :: Applicative f => e -> ResultT e f a
raiseT e =
hoist (raise e)
raiseAllT :: Applicative f => [e] -> ResultT e f ()
raiseAllT es =
hoist (raiseAll es)
accumulateT :: (Traversable t , Applicative f) => t (ResultT e f a) -> ResultT e f (t a)
accumulateT results =
ResultT (accumulate <$> traverse runResultT results)
accumulateT_ :: (Traversable t , Applicative f) => t (ResultT e f a) -> ResultT e f ()
accumulateT_ results =
ResultT (accumulate_ <$> traverse runResultT results)
fromExceptT :: Functor f => ExceptT e f a -> ResultT e f a
fromExceptT excT =
ResultT (fromEither <$> runExceptT excT)
instance State.MonadState s m => State.MonadState s (ResultT e m) where
state f =
lift (State.state f)