You can picture return x
as meaning "Give me a state, and I'll give you back that state and x". Then you can think of x >>= f1
as "Give me a state, and I'll give that to x
; once it returns a state and a value, I'll give those to f
and pass what f
gives me on to you."
Here's an analogy with function composition:
f, g, h :: a -> a
j = f . g . h :: a -> a
j
is a function that takes an a
, and returns an a
. Along the way, that value is first given to h
, whose output goes to g
, whose output goes to f
, whose output is returned.
Look at "composition" of functions that return State
values.
f', g', h' :: a -> State s a
j' a = return a >>= h' >>= g' >>= f'
Think of State
as being a way of "hiding" a function argument. You could compose them manually like this:
f'', g'', h'' :: a -> s -> (a, s)
-- We could make this point-free by leaving h curried, but this
-- is nicely consistent.
j'' a s = (uncurry f'') . (uncurry g'') . (uncurry h'') $ (a, s)
but the State
monad effectively does that for you with its implementation of >>=
.
Note that j'
only takes an initial value, while j''
takes an initial value and an initial state. That's because the function that would take that state for j'
is still wrapped up in a State
value; we use runState
to retrieve that function so that an initial state can be supplied to the first function in the stack.
(runState j') s0 -- parentheses optional, shown for emphasis
s
is the current state, the function wrapped by theState
newtype returns the result and new state. – Leeinstance Monad (State s)
? Implying the input is that 's'? Need a cold-hard answer using the definition itself. – SoyTeinsrunState
function which takes the initial state and the computation to run e.g.runState (return 1) "state" => (1, "state")
– LeeState s a
can be seen as a machine requiring a current states
, and modifying it while also returning a value of typea
. – chi