2012-02-10 92 views
3

我使用network-conduit下面的代码有问题,里面的新来源:如何添加管道哈斯克尔

import Data.Conduit.List as CL 
import Data.Conduit.Text as CT 
import qualified Data.ByteString.Char8 as S8 
import qualified Data.Text as TT 

mySource :: ResourceT m => Integer -> Source m Int 
mySource i = {- function -} undefined 

myApp :: Application 
myApp src snk = 
    src $= CT.decode CT.ascii 
     $= CL.map decimal 
     $= CL.map {-problem here-} 
     $$ src 

在问题的地方,我想写类似

\t -> case t of 
    Left err = S8.pack $ "Error:" ++ e 
    Right (i,xs) = (>>>=) mySource 
       {- or better: 
        do 
        (>>>=) mySource 
        (<<<=) T.pack xs 
        -} 

其中(>>>=)功能推mySource输出到下一级 (<<<=)正在发送功能回到上一级

+0

'conduit'是否支持向上游发送数据?我知道'管道'呢。也许你需要使用'pipes'作为你的用例。 – Cactus 2016-03-30 06:54:10

+0

'Conduit'可以用'leftover'将数据重新输入到它自己的输入中,但是在这里,'Conduit'想要将输入推回到它的上游'Conduit'的输入中,这是不可能的。在这种情况下应该使用解析器'Conduit'。 – pat 2017-11-27 21:20:02

回答

1

网络将字节流切分为任意ByteString块。使用上面的代码,那些ByteString块将被映射到Text的块,并且Text的每个块将被解析为decimal。然而,表示单个decimal的十进制数字串可以跨两个(或更多)Text块分开。另外,如您所知,使用decimal可以将Text区块的其余部分作为decimal的一部分未被分析,您尝试将其重新插入输入流。

这两个问题都可以通过使用Data.Conduit.Attoparsec. conduitParserEitherData.Attoparsec.Text.decimal来解决。请注意,仅仅解析decimal是不够的;您还需要处理decimal之间的某种分隔符。

它也不可能拼接从CL.map一个Source,因为CL.map的类型签名

map :: Monad m => (a -> b) -> Conduit a m b 

传递给map功能得到一个机会,每个输入a转变成一个单一的输出b,不是b的流。要做到这一点,您可以使用awaitForever,但您需要将Source转换为ProducertoProducer)以便类型匹配。

但是,在您的代码中,您尝试向ByteString的下游发送下游解析错误,但输出mySourceInt,这是一种类型错误。在这两种情况下,您必须提供ByteString的流;在成功的语法分析的情况下可以返回通过融合其它ConduitConduit“只要它与ByteString输出结束了S:

... 
$= (let f (Left err) = yield $ S8.pack $ "Error: " ++ show err 
     f (Right (_, i)) = toProducer (mySource i) $= someOtherConduit 
    in awaitForever f) 

其中someOtherConduitInt”从mySource s和源ByteString的。

someOtherConduit :: Monad m => Conduit Int m ByteString 

最后,我相信你的意思的snk在管,而不是src的一端连接。

+0

代码是为conduit-0编写的。4或者类似的东西,那里根本没有'生产者','消费者'和'管道',剩下的东西也不在那里。我没有这个问题在我身边5年或更长时间,我不确定我是否能够记住我为什么要用这种方式解决问题,并且如果回答涵盖了我实际上遇到的问题。它会告诉我们正确的事情,所以这些日子对于使用导管的人来说可能是有用的,所以我将其标记为已接受。 – qnikst 2017-12-04 19:05:29