如何将多个管道合并为一个,反之亦然

时间:2013-01-30 14:46:05

标签: haskell conduit

是否可以将多个管道合并为一个,反之亦然?

我正在努力实现以下功能。

merge :: (Monad m) => [Pipe l i o u m r] -> Pipe [l] [i] [o] m [r]

split :: (Monad m) => Pipe [l] [i] [o] m [r] -> [Pipe l i o u m r]

2 个答案:

答案 0 :(得分:3)

从您的评论中,您可以通过将一些接收器链接在一起,更轻松地完成您尝试做的事情:

import Data.Conduit
import Data.Serialize.Put (putListOf, putWord32le)
import qualified Data.Conduit.Binary as Cb
import qualified Data.Conduit.List as Cl
import qualified Data.Conduit.Cereal as Cc

main :: IO ()
main = do
  let source = Cl.sourceList [[1,2,3],[4,5,6],[7,8,9]]
      encoder = Cc.conduitPut $ putListOf putWord32le

  runResourceT . runPipe $ source >+> do
    Cl.isolate 1 >+> encoder >+> Cb.sinkFile "/tmp/1.bin"
    Cl.isolate 1 >+> encoder >+> Cb.sinkFile "/tmp/2.bin"
    Cl.isolate 1 >+> encoder >+> Cb.sinkFile "/tmp/3.bin"
    Cl.sinkNull

答案 1 :(得分:1)

正如其他人所评论的那样,合并管道具有多种语义。

我知道在pipes-core(Paolo Capriotti的Gabriel Gonzalez的pipes库的分支,这是像conduit这样的迭代的另一种实现),有一些非常通用的代码用于幺半群和乘法类别。

http://hackage.haskell.org/packages/archive/pipes-core/0.1.0/doc/html/Control-Pipe-Category.html#t:PipeC

例如,使用PipeC,一个移动类型变量以使PipeC m r成为有效类别的新类型,我们可以将设置独立信号复用为Either s。

您还可以在sequence个实例中使用Monad之类的内容。

sequence :: [m a] -> m [a]

将“垂直”排序各种管道(一个运行然后运行下一个),让我们写一些类似的东西(使用来自Gonzalez Control.Pipe.Pipe包的pipes

takeNPipe :: Int -> Pipe a b m [a]
takeNPipe n = sequence (replicate n await)

您要求的类型同时暗示了这两种“合并”。这是(我相信)不可能,因为你想同时想要并行(多路复用)和顺序(垂直)合成。