我试图理解管道概念的不同实现之间的差异。导管和管道之间的区别之一是它们如何将管道融合在一起。导管有

(>+>) :: Monad m
      => Pipe l a b r0 m r1 -> Pipe Void b c r1 m r2 -> Pipe l a c r0 m r2

而管道有
(>->) :: (Monad m, Proxy p)
      => (b' -> p a' a b' b m r) -> (c' -> p b' b c' c m r) -> c' -> p a' a c' c m r

如果我对管道正确理解,则当两个管道中的任何一个管道停止时,将返回其结果,而另一个管道将停止。使用导管时,如果左管完成,则其结果将向下游发送到右管。

我想知道,管道方法的好处是什么?我想看一些示例(最好是真实世界),该示例使用管道和>+>易于实现,但使用管道和>->难以实现。

最佳答案

以我的经验,上游终结器在现实中的好处非常渺茫,这就是为什么此时它们不在公共(public)API中隐藏的原因。我想我只在一段代码中使用过它们(wai-extra的多部分解析)。

在最一般的形式中,管道使您既可以生成输出值流,又可以生成最终结果。当您将该Pipe与另一个下游Pipe融合时,该输出值流将成为下游的输入流,而上游的最终结果将成为下游的“上游终结器”。因此,从这个角度来看,具有任意上游终止符可实现对称的API。

但是,在实践中,实际上很少使用这样的功能,并且由于它只会混淆API,因此在1.0版本中它被隐藏在.Internal模块中。一种理论上的用例可以是:

  • 您有一个产生字节流的Source。
  • 管道,该管道消耗字节流,将哈希计算为最终结果,然后将所有字节向下传递。
  • 一个接收器,它消耗字节流,例如,将其存储在文件中。

  • 使用上游终结器,您可以将这三个连接起来,并将管道的结果作为管道的最终结果返回。但是,在大多数情况下,还有另一种更简单的方法可以实现相同的目标。在这种情况下,您可以:
  • 使用conduitFile将字节存储在文件中,然后将哈希管道转换为哈希接收器,并将其放置在下游
  • 使用zipSinks将哈希接收器和文件写入接收器合并到一个接收器中。
  • 关于haskell - 导管的上游类型参数的真正好处是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15258406/

    10-11 22:23