haskell - Pipes (Haskell lib) - 具有不同状态 monad 的管道

标签 haskell haskell-pipes

我的目标是使最后产生的值等于 80 (40 + 40)(见下面的代码)...

import Pipes
import Pipes.Prelude
import Pipes.Lift
import Control.Monad.State.Strict

data Input = A Integer | B Integer | C Integer

main :: IO ()
main = runEffect $ each [A 10,B 2,C 3,A 40,A 40] >-> pipeline >-> print


pipeline :: Pipe Input Integer IO ()
pipeline = for cat $ \case
  A x -> yield x >-> accumulate
  B x -> yield x
  C x -> yield x

accumulate :: Pipe Integer Integer IO ()
accumulate = evalStateP 0 accumulate'


accumulate' :: Pipe Integer Integer (StateT Integer IO) ()
accumulate' = go
  where
    go = do
        x <- await
        lift $ modify (+x)
        r <- lift get
        yield r
        go


在这个例子中输入 A s 不累积... yield x >-> accumulate在输入 A 上做我所期望的,流每次都是一个新的......

具有不同状态 monad 的管道按顺序运行良好,但在这里我想以某种方式将它们嵌套在案例模式中(就像一个子流)......

最佳答案

问题是你打电话evalStateP为时过早,放弃您希望在对 accumulate 的调用之间保留的状态.尝试这样的事情:

pipeline :: Pipe Input Integer IO ()
pipeline = evalStateP 0 $ for cat $ \case
  A x -> yield x >-> accumulate
  B x -> yield x
  C x -> yield x

accumulate :: Pipe Integer Integer (StateT Integer IO) ()
accumulate = for cat $ \x -> do
        modify (+x)
        r <- get
        yield r

请注意 Proxy有一个 MonadState例如,如果您使用 mtl,则无需手动提升状态操作。 .

关于haskell - Pipes (Haskell lib) - 具有不同状态 monad 的管道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58859184/

相关文章:

haskell - 修复 OCaml 中的数据类型

haskell - 连接管道与返回不同值的消费者和生产者

haskell - Haskell 中字节流的高效流式传输和操作

haskell - 如何将 IO 操作的输出传输到 haskell 中的进程中

haskell - Iteratees和FRP之间有什么联系?

haskell - 何时选择插件以及何时选择提示

haskell - 为什么我的程序在播放光泽动画后立即退出?

haskell - 在管道内运行单态消费者

haskell - 当我并行运行大量 http 请求时,我得到 "no such protocol name: tcp"

Haskell hClose 阻塞