机器和管道(或其他类似的库)之间的概念差异是什么?

Pet*_*lák 28 haskell conduit transducer-machines

我想学习这个概念,这样我就能理解和使用诸如机器之类的库.

我试图关注RúnarBjarnason关于机器的讨论,但信息太少,基本上只是一堆数据类型.我甚至无法理解什么k

newtype Machine k o = Step k o (Machine k o)
data Step k o r = Stop
                | Yield o r
                | forall t . Await (t -> r) (k t) r
Run Code Online (Sandbox Code Playgroud)

或者t它是什么以及它为什么被量化.或者,管道式库和机器之间的概念差异是什么?

Edw*_*ETT 45

conduit并且pipes都远超过成熟machines,但是-这说的- machines正试图采取比不同的路径conduitpipes.

有了machines,我正在尝试在类型参数方面使用相对简单的API.二者conduitpipes选择通过使用5-6不同类型的可变参数,以统一他们所有的概念.

机器采用不同的方法将机器(或Plan)参数化为"输入语言",这使得所有的责任都放在一个额外的参数上(或者在a的情况下为两个Plan).此外,通过选择以这种方式参数化输入语言,它开辟了使用可以从多个输入源确定性地接受输入(非)的机器的可能性.结果基本上只是一个带有额外"发射"指令的免费monad!

作为对如何构建和使用机器的更严格的策略的交换,它最终可以提供关于结果代码的渐近性的更好的安全性.

也就是说,pipes并且conduit有很多现实世界的使用,machines或多或少是我的游乐场,RúnarBjarnason和Paul Chiusano.

它目前适合处理您打算完全使用的输入,但对于处理复杂资源或解析而言,不如使用其他两个API获得的那样.

现在,关于量词!

t实际上存在量化.通过这样做,我们可以使Monad机器不关心k参数的功能性.这很重要,因为Source实施方式.如果我不需要Source工作,那么我们可以使用更简单的方法

data Step k o r = Stop
                | Yield o r
                | Await (k r) r
Run Code Online (Sandbox Code Playgroud)

这会产生令人遗憾的副作用,当你去Source编写一台带有a的机器时,编译器就不知道Functor要选择哪个实例,而你会在不必要的类型注释中游泳.

存在量化是我在处理kan-extensions包时所采用的技巧.它是其中一种Yoneda类型的概括.

  • `ka`是您正在为数据提供的任何请求的类型.`a`代表请求的结果.`Await`实际上有两个参数:"如果请求成功则该怎么做"和"失败怎么办".对于单个输入,您可以使用k =( - >)i`,以便`Machine(( - >)i)`被赋予一个函数来自`(i - > r)`,您可以提供输入.使用`Tee`,您可以使用两个函数中的一个,这样您就可以单独阻止任一输入."Wye"允许您同时阻止其中一个或两个输入.`Is`就像上面的`( - >)`一样使用. (4认同)
  • 通过将`Plan`与`Machine`分开,我们可以做两件事.第一个"计划"在内部采用CPS /密码形式.这使得(>> =)便宜,即使你已经离开了相关的绑定(与`pipes`不同),而`Machine`是更传统的ADT形式,这使得模式匹配更便宜.这意味着建立一个"计划"的便宜,但运行"机器"便宜.使用一种类型的"管道"方法意味着一个角色受到影响.特别是如果你管道然后绑定,你需要支付在管道中采取多少步骤来克服(>> =)! (3认同)
  • 此外,通过将"Plan"与"Machine"分开,我们可以得到两个不同的monad.`Plan`的monad基本上是输入语言中的自由monad请求,然后是输出通道上的排放,而`Machine`的monad更像是一个列表monad,在那里你可以忘记地将所得到的机器链接在一起.每个都有不同的用途,但值得注意的是,我们可以使用几乎标准的组合器来处理每个,而不是为所有东西组成我们自己的类/类型. (3认同)
  • 如果你看一下`scalaz`中的'Trampoline`代码,你会看到如何避免完整的结构重新遍历以及如何避免为非平凡的输入吹掉堆栈.遗憾的是,scala中可扩展/工作的monadic代码需要付出实际代价.蹦床可以慢50倍,所以你必须在scala中选择3个选项:快速和松散,同时崩溃非平凡的输入,缓慢但正确的堆上的帧,或者使用副作用和非局部推理乱丢你的代码. (3认同)