gpt4 book ai didi

Haskell 导管 : is it possible to optionally have the result of a source?

转载 作者:行者123 更新时间:2023-12-05 01:01:17 27 4
gpt4 key购买 nike

我有从 Data.Conduit 构建的以下类型:

type Footers = [(ByteString, ByteString)]

type DataAndConclusion = ConduitM () ByteString IO Footers

第二种类型的想法是“生成大量 ByteString,如果您可以生成所有这些,则返回一个页脚”。条件是因为管道是由下游函数控制的,所以 DataAndConclusion 的消费者可能不需要消费它的所有项目,在这种情况下不会达到返回。这正是我需要的行为。但是当到达源的末尾时,我想要生成的页脚。例如,如果 DataAndConclusions 增量计算 MD5 并且只有在整个消息由下游处理时才需要这样的 MD5,这将很有用(例如,下游可以简单地通过网络发送它,但它没有意义如果套接字在下游发送最后一块之前关闭,则完成计算并发送 MD5)。

所以,基本上我想用这个签名来使用 DataAndConclusions:
 type MySink = Sink ByteString IO ()

mySink :: MySink
mySink = ...

difficultFunction :: ConduitM () a2 m r1 -> ConduitM a2 Void m r2 -> m (Maybe r1)

问题是,有没有办法实现“difficultFunction”?如何?

最佳答案

绝对应该有一个很好的解决方案,但我无法使用 ConduitM 构建它原语。有签名的东西

ConduitM i a m r1 -> ConduitM a o m r2 -> ConduitM i o m (Maybe r1, r2)

看起来具有此签名的原始函数将是管道库的一个很好的补充。

尽管如此,@danidiaz 关于 StateT 的建议引导我使用以下通用解决方案,将整个计算提升到 WriterT在内部为了记住第一个管道的输出,如果它到达:
import Control.Monad
import Control.Monad.Trans
import Control.Monad.Trans.Writer
import Data.Conduit
import Data.Monoid
import Data.Void

difficultFunction :: (Monad m)
=> ConduitM () a2 m r1 -> ConduitM a2 Void m r2
-> m (r2, Maybe r1)
difficultFunction l r = liftM (fmap getLast) $ runWriterT (l' $$ r')
where
l' = transPipe lift l >>= lift . tell . Last . Just
r' = transPipe lift r

(未经测试!)

关于Haskell 导管 : is it possible to optionally have the result of a source?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28523958/

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