J Fritsch
J Fritsch

Reputation: 3358

How do I define the initial state in the State Monad?

I found this partially on http://www.haskell.org/haskellwiki/State_Monad but it is not clear to me how I would define the initial state of c and f.

It works with IORefs though but I do not need global mutable data.

increment :: StateT Integer IO Integer
increment = do
        n <- get 
        put (n+1)
        return n

plusOne :: Integer -> IO Integer
plusOne n = execStateT increment n   

printTChan mtch = do
        forever $ do
        m <- atomically $ readTChan mtch
        case m of
             "ping" -> plusOne c
             _ -> plusOne f
        print (c)

Upvotes: 0

Views: 173

Answers (1)

hammar
hammar

Reputation: 139900

When working with StateT, you can think of run/eval/execStateT as marking the scope of the state, so what you have there is just a fancy way of writing this:

plusOne n = return (n+1)

Since you're ignoring the result of these actions, this has no effect whatsoever.

If you want to carry the state across your entire computation, you need to structure your code so that the whole thing runs in StateT:

printTChan mtch = flip evalStateT (c0, f0) $ do
    forever $ do
        m <- liftIO . atomically $ readTChan mtch
        case m of
            "ping" -> modify incrementC
             _     -> modify incrementF
        (c, f) <- get
        liftIO $ print c

incrementC (c, f) = (c+1, f)
incrementF (c, f) = (f, c+1)

Now, you can fill in the initial state values in place of (c0, f0).

Upvotes: 7

Related Questions