【发布时间】:2014-03-15 15:03:57
【问题描述】:
在下面的代码中我该怎么做
更改
stdoutCharConsumer以便在打印输入流中的所有数据后打印一个换行符实现
mixin和mixin'
不进入 Pipes.Internal?可能吗?我需要类似next Producers 的函数。
我使用 Pipes 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 也是不可能的。是真的吗?
【问题讨论】:
-
您了解
interleave的工作原理吗?请注意,当管道p完成时,next p返回Left result。 -
我想我理解它,但它适用于生产者,而不是管道。这就是为什么我将
interleave留在这里作为我为 Producers 拥有并希望为 Pipes 拥有的示例的原因 -
抱歉,我以为
next有更通用的类型。如果您确实深入了解Pipes.Internal,请查看MonadPlus实例以获取灵感。可能您可以调整mplus实现背后的想法,以获得类似于interleave的更一般的Proxy值。
标签: haskell haskell-pipes