我已使用zipSinks :: Monad m => Sink i m r -> Sink i m r' -> Sink i m (r, r')
,但它被视为已弃用。
答案 0 :(得分:7)
修改强>
考虑到这一点后,我不认为使用当前版本的Data.Conduit是可能的。管道不是类别,因此&&&
是不可能的。并且我无法想到从上游提取结果,逐步将它们提供给两个接收器,并在第一个接收器完成时短路。 (虽然我认为Data.Conduit.Util.zipSinks
不会以这种方式短路,但这似乎是非常可取的。)当然,除了两个接收器上的模式匹配(如包中的zipSinks
一样) ),但这就是我们在这里要避免的。
那就是说,我会爱在这里被证明是错误的。
它不漂亮,但你可以用一种显而易见的方式做到这一点。
首先进口:
module Main where
import Control.Monad.Trans
import Data.Conduit
import qualified Data.Conduit.Binary as CB
import qualified Data.Conduit.List as CL
import qualified Data.Conduit.Text as CT
import qualified Data.Conduit.Util as CU
import Data.Maybe
import Data.Text (unpack)
现在为zipSinks
。基本上,您希望创建一个从上游提取输入并将其分别发送到每个子接收器的接收器。在这种情况下,我使用CL.sourceList
来执行此操作。如果await
返回Nothing
,则maybeToList
会返回一个空列表,因此子汇也会在没有输入的情况下运行。最后,每个子汇的输出然后被输入元组。
zipSinks :: Monad m => Sink i m r -> Sink i m r' -> Sink i m (r, r')
zipSinks s1 s2 = do
l <- fmap maybeToList await
o1 <- lift $ CL.sourceList l $$ s1
o2 <- lift $ CL.sourceList l $$ s2
return (o1, o2)
以下是使用zipSinks
的一些示例。它似乎在IO
内部及其外部工作正常,并且在我做的少数测试中,输出与使用旧zipped'
创建的zipSinks
的输出匹配。
doubleHead :: Monad m => Sink Int m (Maybe Int)
doubleHead = await >>= return . fmap (2*)
-- old version
zipped' :: Monad m => Sink Int m (Maybe Int, Maybe Int)
zipped' = CU.zipSinks CL.head doubleHead
-- new version
zipped :: Monad m => Sink Int m (Maybe Int, Maybe Int)
zipped = zipSinks CL.head doubleHead
fromList = CL.sourceList [7, 8, 9] $$ zipped
-- (Just 7, Just 14)
fromFile :: String -> IO (Maybe Int, Maybe Int)
fromFile filename = runResourceT $
CB.sourceFile filename
$= CB.lines
$= CT.decode CT.utf8
$= CL.map (read . unpack)
$$ zipped
-- for a file with the lines:
--
-- 1
-- 2
-- 3
--
-- returns (Just 1, Just 2)
答案 1 :(得分:6)
((包是conduit-0.5.2.3。整个module只是为了向后兼容。))
[修改强>
所以,即使类型是正确的,我直截了当的monadic猜测(见下面)似乎错误。 现在,我只能猜到答案是:
替换功能仍在开发中,与所有Pipe / Conduit和类似的概念和库非常相似。
我等待下一个API来解决这个问题,然后仍然使用zipSink
。
(也许它只是放错地方。)
[<强> /修改
我不熟悉这个软件包,但它不会像这样做吗?
zipSinks :: Monad m => Sink i m r -> Sink i m r' -> Sink i m (r, r')
zipSinks s1 s2 = (,) <$> s1 <*> s2
毕竟是Monad。 (Functor,Applicative)
zipSinks :: Monad sink => sink r -> sink r' -> sink (r, r')
zipSinks s1 s2 = liftM2 (,) s1 s2