是否可以将多个管道合并为一个,反之亦然?
我正在努力实现以下功能。
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]
From your comment, it sounds like you can more easily accomplish what you're trying to do just by chaining some sinks together:
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
正如其他人评论的那样,合并管道具有多种语义。
我知道在pipes-core
(Paolo Capriotti 的 Gabriel Gonzalezpipes
库的分支,它是 iteratees 的另一种实现conduit
)中,有一些非常通用的用于单曲面和乘法类别的代码。
例如,使用PipeC
,一个移动类型变量以形成PipeC m r
有效类别的新类型,我们可以将独立信号多路复用为Either
s。
您还有类似的东西sequence
适用于整个Monad
实例。
sequence :: [m a] -> m [a]
这将“垂直”排列各种管道(一个运行然后下一个)让我们编写类似的东西(使用Control.Pipe.Pipe
来自 Gonzalez 的pipes
包)
takeNPipe :: Int -> Pipe a b m [a]
takeNPipe n = sequence (replicate n await)
您要求的类型同时暗示了这两种“合并”。这(我相信)是不可能的,因为您同时想要并行(多路复用)和顺序(垂直)组合。