[Haskell-beginners] Join'ing a State Monad, example from LYH

Francesco Ariis fa-ml at ariis.it
Sat Feb 10 15:25:40 UTC 2018


On Sat, Feb 10, 2018 at 02:48:07PM +0000, Olumide wrote:
> I find the following implementation of join in the text is hard to
> understand or apply
> 
> join :: (Monad m) => m (m a) -> m a
> join mm = do
> 	m <- mm
> 	m

Hello Olumide,

remember that:

    join :: (Monad m) => m (m a) -> m a
    join mm = do m <- mm
                 m

is the same as:

    join :: (Monad m) => m (m a) -> m a
    join mm = mm >>= \m ->
              m

In general remember that when you have a "plain" value, the last line
of a monadic expression is often:

    return someSimpleVal

So:

    monadicexpr = do x <- [4]
                     return x -- can't just write `x`

When you have a monad inside a monad, you can just "peel" the outer
layer and live happily thereafter:


    monadicexpr = do x <- [[4]]
                     x -- result will be: [4], no need to use return
                       -- because [4] (and not 4) is still a
                       -- list monad

As for State, remember that State is:

    data State s a = State $ s -> (a, s) -- almost

So a function that from a state s, calculates a new state s' and returns
a value of type `a`.
When we use the bind operator in a do block, it's like we're extracting
that value of type `a`

    monadicexpr = do x <- someState
                     return x -- again we need to wrap this value
                              -- before returning it, this state being
                              --
                              -- \s -> (x, s)
                              --
                              -- i.e. we do nothing to the parameter state
                              -- and place `x` as a result.
                              --

Same trick there, if `x` is actually a State-inside-State (e.g. of
type `State s (State s a)`), there is no need for wrapping anymore.

Does this make sense?
-F


More information about the Beginners mailing list