I have a question regarding the usage of the state monad if a function and its argument, that is also a function, both change the state.
here is the short info:
function foo
changes the state
function bar
changes the state
I want to call:
foo bar
if I call bar
alone, the the state is set to "bar"
if I call foo bar
then the state is only "foo" instead of "foobar", so it seems that bar
did not change the state, and I don't understand why.
Any clarification is appreciated.
Here is the full code:
module Main where
import Control.Monad.State
main :: IO ()
main = do
a <- execStateT test1 ""
print a
a <- execStateT test2 ""
print a
type MyState = String
type MyStateMonadT = StateT MyState IO
test1 :: MyStateMonadT ()
test1 = do
bar
return ()
test2 :: MyStateMonadT ()
test2 = do
foo bar
return ()
data Foo = Foo
data Bar = Bar
foo :: MyStateMonadT Bar -> MyStateMonadT Foo
foo bar = do
modify (++"foo")
return Foo
bar :: MyStateMonadT Bar
bar = do
modify (++"bar")
return Bar
The problem is that you're not actually calling bar
inside foo
.
You can do that using _ <- bar
.
This appends "foobar"
to the state:
foo :: MyStateMonadT Bar -> MyStateMonadT Foo
foo bar = do
modify (++"foo")
_ <- bar
return Foo
and this appends "barfoo"
:
foo :: MyStateMonadT Bar -> MyStateMonadT Foo
foo bar = do
_ <- bar
modify (++"foo")
return Foo