Search code examples
haskellstate-monad

haskell state monad in function and argument


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

Solution

  • 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