首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >管道(Haskell lib) -具有不同状态的管道

管道(Haskell lib) -具有不同状态的管道
EN

Stack Overflow用户
提问于 2019-11-14 22:32:15
回答 1查看 94关注 0票数 2

我的目标是生成的最后一个值等于80 (40 + 40) (参见下面的代码)……

代码语言:javascript
复制
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没有累加...输入A上的yield x >-> accumulate确实做了我期望的事情,每次流都是一个新的流...

具有不同状态monad的管道顺序工作得很好,但在这里,我想以某种方式将它们嵌套在case模式中(类似于substream )……

EN

回答 1

Stack Overflow用户

发布于 2019-11-14 23:25:17

问题是,您过早地调用了evalStateP,丢弃了您希望在对accumulate的调用中保留的状态。尝试如下所示:

代码语言:javascript
复制
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,则不需要手动提升状态操作。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58859184

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档