how does the State monad actually work?

I am trying to understand how the State ends up in the function. foo :: State Int String foo = do tmp <- get put (tmp + 1) return "blah" when invoked as print $ evalState foo 0 I get "blah" as expected. When I switch to execState I get the value 1. This is what confuses me. Where is the State coming from if it is not passed into foo? What are get and put operating on? Desugared foo becomes: (get >>= \tmp -> put (tmp + 1)) >> return "blah" Which shows my confusion perfectly. Neither get nor put take a parameter. Why is that? How does return know to include them in the new State value? Especially considering the use of ">>". Obviously I can use State instances following examples like this but I can not reason with them since there is still a feeling of magic to them. Thanks.

I highly recommend reading some of the tutorials that show how to derive the
state monad. The type of state is really a function that takes a parameter
and returns a state tupled with a value. Yet another haskell tutorial has
quite a good chapter on this.
On 24 May 2011 08:40, "Sean Perry"

On Tue, May 24, 2011 at 9:50 AM, Benjamin Edwards
I highly recommend reading some of the tutorials that show how to derive the state monad. The type of state is really a function that takes a parameter and returns a state tupled with a value. Yet another haskell tutorial has quite a good chapter on this.
I get "blah" as expected. When I switch to execState I get the value 1. This is what confuses me. Where is the State coming from if it is not passed into foo? What are get and put operating on?
get does not need a parameter. It executes in the state monad, and get is defined to retrieve the computation's enclosing state. Put *does* take a
Personally, I think one should have a look at the "Monads" chapter in RWH, and maybe also LYAH. Here are the respective links: http://book.realworldhaskell.org/read/monads.html#monads.state and http://learnyouahaskell.com/for-a-few-monads-more#state (also take a look at the preceding chapter in LYAH, since it introduces Monads more generally.) parameter, and that is the new state for the state monad. Mind you, the state is not *implicit* -- it is, in fact, made explicit in the type signature; but it looks as if it were implicit in the definition of your function. In any case, you do not need to supply the value of the state to either get or put as a parameter, because both are designed around chaining stateful computations together without passing around the state in the function's arguments! execState and runState just do different things. Look at the type signatures using hoogle: execState :: State s a -> s -> s runState :: State s a -> s -> (a, s) evalState :: State s a -> s -> a State itself is defined as a tuple of state and result. runState is the function you use to retrieve both. evalState and execState just produce special cases of runState (i.e. they retrieve either one or the other member of the tuple.) HTH, Aleks

On 24 May 2011 09:41, Sean Perry
when invoked as
print $ evalState foo 0
I get "blah" as expected. When I switch to execState I get the value 1. This is what confuses me. Where is the State coming from if it is not passed into foo? What are get and put operating on?
If you write it like this print $ (execState foo) 0 and note that execState foo :: Int -> Int it's easier to see that evalState foo returns a *function* that takes an initial state and then operates on this. Hope this makes it a bit clearer. :-) -- Erlend Hamberg ehamberg@gmail.com
participants (4)
-
Aleksandar Dimitrov
-
Benjamin Edwards
-
Erlend Hamberg
-
Sean Perry