gpt4 book ai didi

haskell - 如何在管道haskell内添加新源

转载 作者:行者123 更新时间:2023-12-02 17:06:51 25 4
gpt4 key购买 nike

我在使用 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输出到下一个级别并且 (<<<=)正在将函数发送回上一级

最佳答案

网络将字节流切割成任意的ByteString大块。通过上面的代码,那些 ByteString block 将被映射到 Text 的 block ,以及 Text 的每个 block 将被解析为 decimal 。然而,一串十进制数字代表单个 decimal可以分为两个(或多个)Text大块。另外,正如您所意识到的,使用 decimal返回 Text 的剩余部分没有被解析为 decimal 的一部分的 block ,您正尝试将其推回到输入流中。

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

也无法拼接 Source来自CL.map ,自 CL.map的类型签名是

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

您传递给 map 的函数有机会转换每个输入a转换为单个输出 b ,不是 b 的流的。为此,您可以使用 awaitForever ,但您需要转换您的 Source成将军ProducertoProducer为了使类型匹配。

但是,在您的代码中,您尝试向下游发送解析错误 ByteString的,但是 mySource 的输出如Int的,这是一个类型错误。您必须提供 ByteString 的流在这两种情况下;成功的解析案例可以返回 Conduit通过融合其他制成Conduit只要最终输出为 ByteString 即可:

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

哪里someOtherConduit沉没Int来自 mySource和来源ByteString的。

someOtherConduit :: Monad m => Conduit Int m ByteString

最后,我相信您的意思是连接 snk在管道末端而不是 src .

关于haskell - 如何在管道haskell内添加新源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9226780/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com