如何在State Monad中定义初始状态?

J F*_*sch 0 haskell

我在http://www.haskell.org/haskellwiki/State_Monad上发现了这一点, 但我不清楚如何定义c和f的初始状态.

它适用于IORefs,但我不需要全局可变数据.

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)
Run Code Online (Sandbox Code Playgroud)

ham*_*mar 7

在使用时StateT,您可以将其run/eval/execStateT视为标记状态的范围,因此您所拥有的只是一种奇特的写法:

plusOne n = return (n+1)
Run Code Online (Sandbox Code Playgroud)

由于您忽略了这些操作的结果,因此无效.

如果要在整个计算中携带状态,则需要构造代码,以便整个运行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)
Run Code Online (Sandbox Code Playgroud)

现在,您可以填写初始状态值来代替(c0, f0).