如何使用管道状态?

时间:2014-02-13 02:01:03

标签: haskell haskell-pipes

我有一个Map Int String -> Proxy () a () Void IO b类型的函数。现在它await s,做任何有价值的东西,然后重新调用自己。我想将其更改为使用State (Map Int String)而不是将其作为参数传递,因此我可以使用forever并且不需要让每个分支都记得递归。我知道我需要使用StateTState与另一个monad合并,但我不明白StateT属于该类型签名的位置,或者我是否需要{ {1}} lift等功能。对于getState (Map Int String)

的函数,正确的类型是什么?

1 个答案:

答案 0 :(得分:16)

注意:Proxy () a () Void = Consumer a,因此我会将此引用为此Consumer

简单的方法是将StateT monad变换图层放在Consumer图层之外,然后立即运行。这是一个例子:

import Control.Monad (forever)
import Control.Monad.Trans.State.Strict
import Pipes

example :: (Show a) => Consumer a IO r
example = flip evalStateT 0 $ forever $ do
    -- Inside here we are using `StateT Int (Consumer a IO) r`
    a <- lift await
    n <- get
    lift $ lift $ putStrLn $ "Received value #" ++ show n ++ ": " ++ show a
    put (n + 1)

......这就是它在行动中的表现:

>>> runEffect $ each ["Test", "ABC"] >-> example
Received value #0: "Test"
Received value #1: "ABC"