Can somebody walk me through this Haskell function (State monad related)?

haskell, monads, state

Solution

...How is puts updating the state in the first place? It seems to just be sitting there doing nothing...

Ah, now I understand your question. You're wondering how `put` (and `get`) work, right?

Maybe an example in JavaScript will help (a language with actual mutable state):

var s; // mutable state
function get() { return s; }
function put(x) { s = x; }

function tick() {
    var n = get();
    put(n + 1);
    return n;
}

I hope this illustrates that, while `n` doesn't change, the internal state still will get updated. If you execute `tick()` twice, the state will be incremented twice.

To get back to Haskell, here's the full definition of (the relevant parts) of the `State` monad:

newtype State s a = State { runState :: s -> (a, s) }

instance Monad (State s) where
    return a = State $ \s -> (a, s)
    m >>= k  = State $ \s -> let
        (a, r) = runState m s
        in runState (k a) r

get   = State $ \s -> (s, s)
put s = State $ \_ -> ((), s)

Now try to expand your `tick` example even further by manually inlining `>>=`, `return`, `get` and `put`. Hopefully it will get more clear how State works.

Problem

``` tick :: State Int Int tick = get >>= \n -> put (n+1) >>= \y -> return n ``` I'm confused as to how `put (n+1)` has any effect on the end result of this function at all. It seems like this function should return the initial state unchanged. I'm trying to run through this in my mind, but I keep running out of room to hold things in place. :\ If someone could walk me through the evaluation of this function, it would be really helpful.

Original source