one question according to the get function of the State Monad:
If I run
runState get 1
I got the result
(1,1)
and this is ok for me because the get function set the result value to the state and in this case the state is 1. Thus, (1,1) is the result. Ok.
But if I run
runState (do{(a,b) <- get; return a}) (False, 0)
I got the result
(False,(False,0))
And this I don't understand.
The get function set the result value to the state and left the state unchanged. So what I would expect is something like this
((False,0),(False,0))
The same with this
runState (do{(a,b) <- get; return b}) (False, 0)
the result is
(0,(False,0))
I don't understand this again as above descripted.
So, it would be very nice if you could explain me this for me strange results. ;)
Thanks in advance
best regards,
jimmy
It's because you do something after the get
, namely you return
one of the components. Ignoring the newtype-wrapping,
return x = \s -> (x,s)
so
do { (a,b) <- get; return a } === get >>= \(a,b) -> return a
expands to
(\s -> (s,s)) >>= \(a,b) -> (\t -> (a,t))
and with the definition of (>>=)
that becomes
\s1 -> let (r,s2) = (\s -> (s,s)) s1
in (\(a,b) -> (\t -> (a,t))) r s2
And when you run that with an initial state of (False,0)
, it unfolds
let (r,s2) = (\s -> (s,s)) (False,0)
~> let (r,s2) = ((False,0),(False,0))
in (\(a,b) -> (\t -> (a,t))) r s2
~> in (\(a,b) -> (\t -> (a,t))) (False,0) (False,0)
~> in (\t -> (False,t)) (False,0) -- match (a,b) with (False,0)
~> in (False, (False,0))
The other case with return b
is similar.
Daniel’s answer is of course correct and complete, so let me try to answer it from a different angle and discuss possible misunderstandings.
You expected ((False,0),(False,0))
to be returned for
runState (do{(a,b) <- get; return a}) (False, 0)
Now to actually get this expected result, you’d have to write, for example,
runState (do{(a,b) <- get; return (a,b)}) (False, 0)
(which is morally equivalent to runState get (False, 0)
.
Maybe you were confusing get
and runState
; the latter returns a tuple where one component is the result of the computation and the other the final state. And indeed you’d take that tuple apart to obtain only the (final) state. get
however has one return value, which is just the (current) state and nothing more – no untupling required. If you do take the tuple apart and return only a
(or b
), then this shows up accordingly as the result of the complete stateful computation, just as you have observed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With