From Thinking Functionally with Haskell (pg 248):
You can think of type
State s a
as beingtype State s a = s -> (a,s)
...
put :: s -> State s () get :: State s s state :: (s -> (a,s)) -> State s a
...
state
can be defined usingput
andget
:state f = do {s <- get; let (a,s') = f s; put s'; return a}
Which I believe can be rewritten this way:
get >>= \s ->
let (a,s') = fs in
put s' >> return a
So what is the purpose of put s'
, if >>
throws away its return value?
>>
doesn't throw away everything from the first argument. The definition for the state monad (ignoring the newtype
)
a >> b = \s -> let (x, s') = a s in b s'
So the state form the first argument is used by >>
, but the 'return value' (the x
component of the result) is ignored. That's the point of the state monad --- to track changes to the state without the programmer having to explicitly take them into account.
Apparently, this isn't explained properly by what the OP has been reading, so here's how you can derive the definition above. The definition of >>
across all monads is
a >> b = a >>= \ _ -> b
The definition of >>=
for the state monad (ignoring newtype
s) is
a >>= f = \ s -> let (x, s') = a s in f x s'
Now, substituting the definition of >>=
into the definition of >>
above and simplifying, we get:
a >> b = let f = \ _ -> b in \ s -> let (x, s') = a s in f x s'
= \ s -> let (x, s') = a s in (\ _ -> b) x s'
= \ s -> let (x, s') = a s in b s'