gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 11:00:09 26 4
gpt4 key购买 nike

我的目标是使最后产生的值等于 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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com