在下面的代码中我该怎么做
更改
stdoutCharConsumer
以便在打印输入流中的所有数据后打印换行符实现
mixin
和mixin'
不进入 Pipes.Internal?是否可以?我需要像生产者的 next
函数这样的东西。
我使用管道4.1.0
#!/usr/bin/env runhaskell
{-# OPTIONS_GHC -Wall #-}
import Pipes
digits, characters :: Monad m => Producer Char m ()
digits = each "0123456789"
characters = each "abcdefghijklmnopqrstuvwxyz"
interleave :: Monad m => Producer a m () -> Producer a m () -> Producer a m ()
interleave a b = do
n <- lift $ next a
case n of
Left () -> b
Right (x, a') -> do
yield x
interleave b a'
stdoutCharConsumer :: Consumer Char IO ()
stdoutCharConsumer = await >>= liftIO . putChar >> stdoutCharConsumer
-- first element of the mixin should go first
mixin :: Monad m => Producer b m () -> Pipe a b m ()
mixin = undefined
-- first element of the pipe should go first
mixin' :: Monad m => Producer b m () -> Pipe a b m ()
mixin' = undefined
main :: IO ()
main = do
-- this prints "a0b1c2d3e4f5g6h7i8j9klmnopqrstuvwxyz"
runEffect $ interleave characters digits >-> stdoutCharConsumer
putStrLn ""
-- this prints "0a1b2c3d4e5f6g7h8i9jklmnopqrstuvwxyz"
runEffect $ interleave digits characters >-> stdoutCharConsumer
putStrLn ""
-- should print "0a1b2c3d4e5f6g7h8i9jklmnopqrstuvwxyz"
runEffect $ characters >-> mixin digits >-> stdoutCharConsumer
putStrLn ""
-- should print "a1b2c3d4e5f6g7h8i9jklmnopqrstuvwxyz"
runEffect $ digits >-> mixin characters >-> stdoutCharConsumer
putStrLn ""
-- should print "a1b2c3d4e5f6g7h8i9jklmnopqrstuvwxyz"
runEffect $ characters >-> mixin' digits >-> stdoutCharConsumer
putStrLn ""
-- should print "0a1b2c3d4e5f6g7h8i9jklmnopqrstuvwxyz"
runEffect $ digits >-> mixin' characters >-> stdoutCharConsumer
putStrLn ""
UPD:现在,在我读到基于拉/推的流之后,我认为即使使用 Pipes.Internal 也是不可能的。这是真的吗?
最佳答案
消费者
和管道
都不知道上游输入结束。为此,您需要来自 pipes-parse
的 Parser
。
与Consumer
相比,Parser
对Producer
有更直接的了解;他们的draw
当发现输入结束时,函数(大致类似于 await
)返回 Nothing
。
import qualified Pipes.Parse as P
stdoutCharParser :: P.Parser Char IO ()
stdoutCharParser = P.draw >>= \ma ->
case ma of
Nothing -> liftIO (putStrLn "\n")
Just c -> liftIO (putChar c) >> stdoutCharParser
要运行解析器,我们调用 evalStateT
而不是 runEffect
:
P.evalStateT stdoutCharParser (interleave characters digits)
至于 mixin
和 mixin'
,我怀疑它们不可能按预期编写工作。原因是结果 Pipe
必须知道上游终止,以便知道何时生成作为参数传递的 Producer
的剩余值。
关于haskell - 如何找到管道的末端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22425432/