迭代I/O在非函数式语言中有意义吗?

本文关键字:语言 有意义 函数 迭代 | 更新日期: 2023-09-27 18:03:04

在Haskell中,基于Iteratee的I/O看起来非常有吸引力。迭代是一种可组合的、安全的、快速的I/O方式,它的灵感来自于"fold"。函数式语言中的reduce函数。基本上,如果要进行遍历,则需要将遍历状态封装到一个所谓的"枚举器"中,该"枚举器"调用"迭代器",而"迭代器"则是一个返回值或请求更多数据的函数,并带有枚举器要调用的延续。因此,只有枚举器知道遍历的状态,而迭代器知道如何处理数据并从中构建值。它的优点是迭代器是自动可组合的,其中一个迭代器的输出被馈送到另一个迭代器以生成一个更大的迭代器。

那么,两个问题:

  • 这个概念在其他语言中是否有意义,比如普通的面向对象语言,或者它只对克服Haskell懒惰I/O的缺点有用?
  • 是否有其他语言的实际实现,特别是c#(因为这是我公司使用的)?(谷歌搜索会发现Scala中提到了迭代器;好吧,我现在对Scala没那么感兴趣)。

迭代I/O在非函数式语言中有意义吗?

如果我理解你所描述的,它听起来很像响应式扩展:

http://channel9.msdn.com/Tags/reactive +扩展

Erik Meijer解释了IObservable是IEnumerable的数学对偶:

http://channel9.msdn.com/Shows/Going +深/Expert-to-Expert-Brian-Beckman-and-Erik-Meijer-Inside-the-NET-Reactive-Framework-Rx

首先,要认识到Haskell的"Lazy IO"是一种hack,它以一种有限的方式打破了纯粹性,允许在惰性使用数据时按需进行I/O。这在非纯语言中是很常见的,而惰性序列在任何地方都可能造成同样的问题。因此,如果您正在做类似这样的事情,例如,将IEnumerable接口暴露给文件并随着序列被枚举而增量地读取它,这实际上没有任何不同。

第二,迭代器和枚举器也可以组合成所谓的枚举对象(以一种有点笨拙的方式)。在这一点上,您有一些东西被输入顺序数据,当它们准备好时产生增量结果,并将这些结果提供给其他东西。这基本上是一种流处理器,这个概念可能比Haskell和c#都要早得多。

第三,迭代器是抽象行为的封装,其内部工作是隐藏的。与ml风格的函数式编程相比,这可以说更符合OO原则,至少在"OO原则"的意义上是这样,而"OO原则"正是那些因为你使用getter和setter而对你大喊大叫,并认为控制流应该通过多态性实现的人所支持的。

考虑到以上,我想说迭代器的概念很适合c#,并且将最自然地实现为一种反向等价的IEnumerable,具有组合数据流对象和"推"接口,而不是标准的LINQ的"拉"样式。