我有一个 type 的函数Map Int String -> Proxy () a () Void IO b
。现在它await
是,用它得到的值做任何事情,然后重新调用它自己。我想将其更改为使用State (Map Int String)
,而不是将其作为参数传递,因此我可以只使用forever
并且不需要让每个分支都记住递归。我知道我需要用来与另一个 monadStateT
结合State
,但我不明白该类型签名的StateT
所属位置,或者我是否需要lift
像get
. 既是 aState (Map Int String)
又是 a 的函数的正确类型是Proxy () a () Void IO b
什么?
问问题
764 次
1 回答
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"
于 2014-02-13T02:15:58.067 回答