0
votes

In the tutorial Learn You a Haskell - chapter 'for-a-few-monads-more', section 'The State monad', it lists the following to define the State Monad:

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

instance Monad (State s) where  
    return x = State $ \s -> (x,s)  
    (State h) >>= f = State $ \s -> let (a, newState) = h s  
                                        (State g) = f a  
                                    in  g newState

Just need an answer to a simple question: What would the input to \s be (since State h = a function that takes a state and outputs a tuple (result, newState); implying that input to \s would just be that function)? Examples welcome

2
s is the current state, the function wrapped by the State newtype returns the result and new state.Lee
But where is the 'current state' coming from? Is it coming from the first line of the definition: instance Monad (State s)? Implying the input is that 's'? Need a cold-hard answer using the definition itself.SoyTeins
No, there is also a runState function which takes the initial state and the computation to run e.g. runState (return 1) "state" => (1, "state")Lee
The current state has to be provided from outside. A value of type State s a can be seen as a machine requiring a current state s, and modifying it while also returning a value of type a.chi

2 Answers

2
votes

You can think of a value of State s a as being a computation which depends on some state parameter which is provided when the computation is run. You can do this by simply unwrapping the contained function and calling it e.g.

runState (return 1) "state"
=> (1, "state")
1
votes

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