SoyTeins
SoyTeins

Reputation: 11

Haskell State Monad - What would the input to lamba \s -> ... be?

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

Upvotes: 0

Views: 193

Answers (2)

Lee
Lee

Reputation: 144206

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")

Upvotes: 2

chepner
chepner

Reputation: 532093

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

Upvotes: 1

Related Questions