【发布时间】:2016-12-01 21:15:02
【问题描述】:
默认情况下,管道是基于拉的。这是由于运算符>-> 是通过+>> 实现的,bind 运算符对于他的拉动类别很有意义。我的理解是,这意味着如果你有producer >-> consumer这样的代码,首先会调用消费者的body,然后一旦等待数据,就会调用生产者。
我在pipes 文档here 中看到,您可以使用Pipes.Core 中的代码(reflect .) 将基于拉的管道转换为基于推送的管道。这意味着相反(如果我错了,请纠正我)在producer >-> consumer 上面的代码中,生产者首先运行,产生一个值,然后消费者尝试消费。这似乎真的很有用,我想知道怎么做。
我还在here 的讨论中看到>-> 没有基于推送的对应物,因为它很容易扭转任何管道(我假设使用反射?),但我真的不知道如何做它或找到任何例子。
这是我尝试过的一些代码:
stdin :: Producer String IO r
stdin = forever $ do
lift $ putStrLn "stdin"
str <- lift getLine
yield str
countLetters :: Consumer String IO r
countLetters = forever $ do
lift $ putStrLn "countLetters"
str <- await
lift . putStrLn . show . length $ str
-- this works in pull mode
runEffect (stdin >-> countLetters)
-- equivalent to above, works
runEffect ((\() -> stdin) +>> countLetters)
-- push based operator, doesn't do what I hoped
runEffect (stdin >>~ (\_ -> countLetters))
-- does not compile
runEffect (countLetters >>~ (\() -> stdin))
【问题讨论】:
标签: haskell haskell-pipes