簡體   English   中英

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

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

我的目標是使最后產生的值等於 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沒有累積... yield x >-> accumulate確實符合我的預期,stream 每次都是新的...

具有不同 state monad 的管道管道順序運行良好,但在這里我想以某種方式將它們嵌套在案例模式中(就像子流一樣)......

問題是您過早地調用evalStateP ,丟棄了 state 您想要在調用中保留的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 ,則無需手動解除 state 操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM