When I was studying Monad Transformer, I decided to create StateT s m a
from scratch with instances for Functor
, Applicative
and Monad
.
This is what I have:
newtype StateT s m a = StateT { runStateT :: (s -> m (a, s)) } instance Functor m => Functor (StateT s m) where -- fmap :: (a -> b) -> StateT s m a -> StateT s m b -- which is (a -> b) -> (s -> m (a, s)) -> (s -> m (b, s)) f `fmap` (StateT x) = StateT $ \ s -> fmap run (x s) where run (a, s) = (f a, s) instance Monad m => Applicative (StateT s m) where -- pure :: a -> StateT s m a pure a = StateT $ \ s -> pure (a, s) -- <*> :: f (a -> b) -> f a -> f b -- which is StateT s m (a -> b) -> StateT s m a -> State s m b k <*> x = StateT $ \ s -> do (f, s1) <- runStateT k s -- :: m ((a -> b), s) (a, s2) <- runStateT x s1 return (f a, s2) instance (Monad m) => Monad (StateT s m) where return a = StateT $ \ s -> return (a, s) -- >>= :: StateT s m a -> (a -> StateT s m b) -> StateT s m b (StateT x) >>= f = StateT $ \ s -> do (v, s') <- x s runStateT (f v) s'
My original intention is to implement Functor (StateT s m)
with Functor m
restriction, Applicative (StateT s m)
with Applicative m
restriction, and Monad (StateT s m) with
Monad m) restriction. However I couldn't do the Applicative
case and had to use Monad m
restriction instead. Is there a way to do it with Applicative m
?
Thank you in advance.