Instances for ReaderT, WriterT, and StateT
To see this all in action, let's define MonadReader, MonadWriter, and
MonadState instances for ReaderT, WriterT, and StateT:
instance Monad m => MonadReader r (ReaderT r m) where
    ask         = ReaderT return
    local mod f = ReaderT $ runReaderT f . mod
    reader f    = ReaderT $ return . f
instance (Monoid w, Monad m) => MonadWriter w (WriterT w m) where
    tell w = WriterT $ return ((), w)
    listen f = WriterT $ do
        (x, w) <- runWriterT f
        return ((x, w), w)
    pass f = WriterT $ do
        ((x, flt), w) <- runWriterT f
        return (x, flt w)
    writer f = WriterT $ return f
instance Monad m => MonadState s (StateT s m) where
    get     = StateT $ \s -> return (s, s)
    put s   = StateT $ \_ -> return ((), s)
    state f = StateT $ return . f
The implementations of ask, tell, get, and put are exactly the ones from
our earlier discussions of the ReaderT, WriterT, and StateT monad
transformers, only now they have become methods of the MonadReader,
MonadWriter, and MonadState instances.
For our MonadReader r (ReaderT r m) instance, local mod f should run f in
some context modified by mod, that is, it should be defined as
local mod f = ReaderT $ \r -> runReaderT f (mod r)
We obtain the definition given above using simple rewriting:
ReaderT $ \r -> runReaderT f (mod r)
    = ReaderT $ \r -> (runReaderT f . mod) r    -- Definition of function composition
    = ReaderT $ runReaderT f . mod              -- \r -> (runReaderT f . mod) r
                                                -- applies (runReaderT f . mod) to its
                                                -- argument and thus is the same as
                                                -- runReaderT f . mod
reader f takes the function f and composes it with return to obtain a
function in the monad m. By wrapping this in ReaderT, this becomes an action
in the ReaderT r m monad.
Similarly, the implementation of writer f for WriterT takes the given pair
f composed of a return value and a log value and turns it into an action in
the underlying monad m, using return f, and then it turns this into a action
in the WriterT w m monad by wrapping it in WriterT.
The implementations of listen and pass are fairly straightforward.
listen f runs f and collects the return value x and log w produced by
f. Since listen f should produce the same log but also return it as part of
the return value of f, we simply return the pair ((x, w), w). pass f runs
f to obtain the pair ((x, flt), w), where (x, flt) is the return value
produced by f, and w is the log. pass f should produce the log flt w and
return x, so we return the pair (x, flt w).
For the MonadState instance of StateT s m, we already observed that the
implementations of get and put are the same we discussed earlier when
introducing the StateT monad transformer. So the only thing to discuss is
state. Its definition is exactly the same as that of reader for
ReaderT r m. We take the pure function f and turn it into the function in
the monad m by composing it with return. Wrapping this function in StateT
then produces an action in the StateT s m monad.
Exercise
When discussing the Reader and State monads, we also introduced
functions
asks :: (r -> a) -> Reader r a
gets :: (s -> a) -> State  s a
Instead of returning the context or current state, they return the result of
applying the given function to the context or current state. These functions
are not part of the MonadReader and MonadState type classes. Yet they
are still available for any monad m that is an instance of MonadReader
or MonadState:
asks :: MonadReader r m => (r -> a) -> m a
gets :: MonadState  s m => (s -> a) -> m a
Implement these two functions. Since all you know about m is that it is an
instance of MonadReader or MonadState, your implementations cannot use
any functions other than the ones provided by these type classes or by the
Monad and Functor type classes, because every MonadReader or
MonadWriter is also a Monad and, hence, a Functor.
Solution
fmap to the rescue. That's all we need. The return type of ask is
m r, and m is a functor. Thus, we transform the value returned by
m by applying a pure function to it. This gives
asks :: MonadReader r m => (r -> a) -> m a
asks f = fmap f ask
or, in infix notation,
asks :: MonadReader r m => (r -> a) -> m a
asks f = f <$> ask
The implementation of gets is completely analogous:
gets :: MonadState  s m => (s -> a) -> m a
gets f = f <$> get
Exercise
When discussing the State monad and the StateT monad transformer, we
also tasked about the function modify, which we can use to modify the
state of the monad using a pure function of type s -> s. Here was the
definition we had for the State monad:
modify :: (s -> s) -> State s ()
modify f = State $ \s -> ((), f s)
This function is not part of the MonadState type class, but it is still
available for any monad that is an instance of this type class. Here's the
type signature:
modify :: MonadState s m => (s -> s) -> m ()
We have a monad m with some state s, and modify f allows us to modify
this state by applying f to
it. Implementmodify. Since all you know aboutmis that it is an instance ofMonadState, your implementation cannot use any functions other thanget,put, andstate`.
Solution
There are two solutions. The more obvious one (?) uses get to access
the current state s, and then writes the updated state f s using
put:
modify :: MonadState s m => (s -> s) -> m ()
modify = do
    s <- get
    put $ f s
or desugaring this using (>>=):
modify :: MonadState s m => (s -> s) -> m ()
modify = get >>= put . f
We can also implement modify using state. Since modify f should
have type m (), if we want modify f = state g, for some function
g, then g must have type s -> ((), s), and the second component of
this pair should be the result of updating the old state by applying
f. Easy enough: g = \s -> ((), f s). Thus,
modify :: MonadState s m => (s -> s) -> m ()
modify f = state $ \s -> ((), f s)