Reputation: 3358
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
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