Created: 2023-02-24 17:59
Given MaybeT
and StateT
:
newtype StateT s m a = StateT { runStateT :: s -> m (a, s) }
instance Functor (StateT s m) where
instance Applicative (StateT s m) where
instance Monad m => Monad (StateT s m) where
newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) }
instance Functor (MaybeT m) where
instance Applicative (MaybeT m) where
instance Monad m => Monad (MaybeT m) where
x >>= f = MaybeT $ do
ma <- runMaybeT x
case ma of
Nothing -> pure Nothing
Just a -> runMaybeT $ f a
What would be the different in having MaybeT .. StateT
vs. StateT .. MaybeT
?
The former produces the state as it was before the error occurred. In other words, the state is maintained and returned, alongside the potential result.
runMaybeState :: MaybeT (StateT s Identity) a -> s -> (Maybe a, s)
runMaybeState act s = runIdentity $ runStateT (runMaybeT act) s
The later introduces transaction semantics, it produces both the state and result if there’s a result.
runStateMaybe :: StateT s (MaybeT Identity) a -> s -> Maybe (a, s)
runStateMaybe act s = runIdentity $ runMaybeT (runStateT act s)