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 aWhat 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) sThe 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)