统计员对管道与管道的利弊分别是什么? [英] What are the pros and cons of Enumerators vs. Conduits vs. Pipes?

查看:96
本文介绍了统计员对管道与管道的利弊分别是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望听到比我更深入了解的人,他们之间的根本区别在于统计员, a href =http://hackage.haskell.org/package/conduit>管道和管道以及主要优点和缺点。一些讨论已经 正在进行中,但它可以很好地进行高级别概述。

作为抽象的统计员/迭代者是由Oleg Kiselyov发明的。它们提供了一种干净的方式来执行可预测(低)资源需求的IO。当前的枚举器包非常接近Oleg的原作。



管道是为Yesod web框架创建的。我的理解是,他们的设计非常快。早期版本的库是高度有状态的。

管道注重优雅。他们只有一个类型而不是几个,形成monad(变换器)和类别实例,并且在设计中非常功能化。



如果你喜欢分类的解释: Pipe 类型就是下面不简单的函子的自由monad p>

  data PipeF abmr = M(mr)|等待(a  - > r)|收益率b r 
实例Monad m => Functor(PipeF a b m)其中
fmap f(M mr)= M $ liftM mr
fmap f(等待g)=等待$ f。 g
fmap f(Yield bp)= Yield b(fp)
- 捐赠:
newtype管道abmr =管道{unPipe :: Free(PipeF abm)r}
派生(Functor,Applicative,Monad)

- 和
实例MonadTrans(管道ab)其中
lift =管道。注意。 M

在实际的管道定义中,这些参数都是烘焙的,但这个定义的简单性令人惊叹。管道在(< +<):: Monad m =>的操作下形成一个类别。 Pipe c d m r - > Pipe a b m r - >管一个d m r ,它取第一个管道产生的任何东西,并将其馈送到等待的第二个管道。

看起来像 Conduits 正在变得更多 Pipe 像(使用CPS代替状态,并切换到单一类型),而Pipes获得更好的错误处理支持,并且可能为发电机和消费者返回不同类型的数据。



这个地区正在迅速发展。我一直在使用具有这些功能的Pipe库的实验变体,并且知道其他人也是如此(请参阅Hackage上的Guarded Pipes软件包),但怀疑Gabriel(Pipes的作者)会在我做。



我的建议是:如果您使用Yesod,请使用Conduits。如果你想让一个成熟的库使用枚举器。如果你主要关心优雅,使用管道。

I'd like to hear from someone with a deeper understanding than myself what the fundamental differences are between Enumerators, Conduits, and Pipes as well as the key benefits and drawbacks. Some discussion's already ongoing but it'd be nice to have a high-level overview.

解决方案

Enumerators/Iteratees as an abstraction were invented by Oleg Kiselyov. They provide a clean way of doing IO with predictable (low) resource requirements. The current Enumerators package is pretty close to Oleg's original work.

Conduits were created for the Yesod web framework. My understanding is that they were designed to be blazingly fast. Early versions of the library were highly stateful.

Pipes focus on elegance. They have just one type instead of several, form monad (transformer) and category instances, and are very "functional" in design.

If you like categorical explanations: the Pipe type is just the free monad over the following ungodly simple functor

data PipeF a b m r = M (m r) | Await (a -> r) | Yield b r
instance Monad m => Functor (PipeF a b m) where
   fmap f (M mr) = M $ liftM mr
   fmap f (Await g) = Await $ f . g
   fmap f (Yield b p) = Yield b (f p)
--Giving:
newtype Pipe a b m r = Pipe {unPipe :: Free (PipeF a b m) r}
  deriving (Functor, Applicative, Monad)

--and
instance MonadTrans (Pipe a b) where
   lift = Pipe . inj . M

In the actual pipe definition these are baked in, but the simplicity of this definition is amazing. Pipes form a category under the operation (<+<) :: Monad m => Pipe c d m r -> Pipe a b m r -> Pipe a d m r which takes whatever the first pipe yields and feeds it to the awaiting second pipe.

It looks like Conduits is moving to be more Pipe like (using CPS instead of state, and switching to a single type) while Pipes are gaining support for better error handling, and perhaps the return of separate types for generators and consumers.

This area is moving quickly. I've been hacking on an experimental variant of the Pipe library with these features, and know other people are as well (see the Guarded Pipes package on Hackage), but suspect that Gabriel (the author of Pipes) will figure them out before I do.

My recommendations: if you are using Yesod, use Conduits. If you want a mature library use Enumerator. If you primarily care about elegance, use Pipe.

这篇关于统计员对管道与管道的利弊分别是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆