简体   繁体   English

Pipes (Haskell lib) - 具有不同 state monad 的管道

[英]Pipes (Haskell lib) - piping pipes with different state monad

My goal is to have the last value produced equal to 80 (40 + 40) (see code below)...我的目标是使最后产生的值等于 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

With this example Input A s are not accumulated... yield x >-> accumulate on Input A does do what I'm expected, the stream is a new one each time...在此示例中,输入A没有累积... yield x >-> accumulate确实符合我的预期,stream 每次都是新的...

Piping pipes with different state monad sequentially works well but here somehow I want to nest them in the case pattern (like a substream somehow)...具有不同 state monad 的管道管道顺序运行良好,但在这里我想以某种方式将它们嵌套在案例模式中(就像子流一样)......

The problem is that you call evalStateP too early, discarding state you want to preserve across calls to accumulate .问题是您过早地调用evalStateP ,丢弃了 state 您想要在调用中保留的accumulate Try something like this:尝试这样的事情:

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

Note that Proxy has a MonadState instance, so you don't need to lift state operations manually if you use mtl .请注意, Proxy有一个MonadState实例,因此如果您使用mtl ,则无需手动解除 state 操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM