I'm trying so hard to wrap my head around the State Monad, and I do not understand the following:
Given the implementation of return
and (>>=)
, when you say State $ \s ->....
, where does s
come from? I mean, when you start performing >>= ... >>=
, doesn't it mean that somewhere in your beginning of the chain you somehow have to provide for that initial parameter?
newtype State s a=State { runState::s->(a,s) }
instance Monad (State s) where
return a=State $ \s->(a,s)
(>>=) m g=State $ \s -> let (a,s')= runState m s in
runState (g a) s'
In (>>=)
you say State $ \s -> runState m s
, and I do not get when is that initial (\s -> ...) argument
(with a REAL argument
) called?
Can someone explain, please?
Later Edit:
Can someone show me how would the initial
state be set, let's say if it needs to get a value using getLine
?
main::IO()
main=do
argument<-getLine
--how do i set initial state with argument?
m >> f1 >> f2 >> f3
when you say
State $ \s ->....
, where doess
come from ?
It will come from the invocation, when runState
will supply the initial state value to the state-monadic value, to run the combined computation it describes:
st = do { x <- get ; return (x+1) }
x = runState st 0 -- x is (1,0)
I also sense another possible misunderstanding on your part: you write: "when is that initial (\s -> ...) argument
called?" There's no "initial" lambda: the lambdas are all nested inside!
do { a <- as; b <- bs; c <- foo b; return c }
translates as
as >>= (\a -> bs >>= (\b -> foo b >>= (\c -> return c)))
so it's not "initial", that's one combined all-enclosing lambda that is called with the initial state!
And then it will call
let (a,s1) = runState as s0
etc. with that "initial" as
in the do
block.