IEnumerable在 OCaml 中
我经常使用 F#。 F# 中的所有基本集合都实现了 IEumberable 接口,因此使用 F# 中的单个 Seq
模块来访问它们是很自然的。这在 OCaml 中可能吗?
另一个问题是 F# 中的 'a seq
是惰性的,例如我可以使用 {1 创建从
或更详细地说:1
到 100
的序列..100}
seq { for i=1 to 100 do yield i }
在 OCaml 中,我发现自己使用以下两种方法来解决此功能:
生成列表:
让记录范围 ab = 如果a>然后 [] 否则 a :: 范围 (a+1) b;;
或诉诸显式递归函数。
第一个生成额外的列表。第二个打破了抽象,因为我需要使用更高阶的函数(例如 map
和 fold
)在序列级别上进行操作。
我知道 OCaml 库有 Stream 模块。但它的功能似乎相当有限,不像F#中的'a seq
那么通用。
顺便说一句,我最近正在使用 OCaml 玩 Project Euler 问题。因此,有相当多的序列操作,在命令式语言中将是具有复杂体的循环。
I use F# a lot. All the basic collections in F# implement IEumberable interface, thus it is quite natural to access them using the single Seq
module in F#. Is this possible in OCaml?
The other question is that 'a seq
in F# is lazy, e.g. I can create a sequence from 1
to 100
using {1..100}
or more verbosely:
seq { for i=1 to 100 do yield i }
In OCaml, I find myself using the following two methods to work around with this feature:
generate a list:
let rec range a b = if a > b then [] else a :: range (a+1) b;;
or resort to explicit recursive functions.
The first generates extra lists. The second breaks the abstraction as I need to operate on the sequence level using higher order functions such as map
and fold
.
I know that the OCaml library has Stream module. But the functionality of it seems to be quite limited, not as general as 'a seq
in F#.
BTW, I am playing Project Euler problems using OCaml recently. So there are quite a few sequences operations, that in an imperative language would be loops with a complex body.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这个 Ocaml 库似乎提供了您所要求的内容。不过我还没用过。
http://batteries.forge.ocamlcore.org/
查看此模块,Enum
http://batteries.forge.ocamlcore.org /doc.preview:batteries-beta1/html/api/Enum.html
我不知何故觉得 Enum 是一个比 Seq 更好的名字。它消除了 Seq 上的小写/大写混淆。
This Ocaml library seems to offer what you are asking. I've not used it though.
http://batteries.forge.ocamlcore.org/
Checkout this module, Enum
http://batteries.forge.ocamlcore.org/doc.preview:batteries-beta1/html/api/Enum.html
I somehow feel Enum is a much better name than Seq. It eliminates the lowercase/uppercase confusion on Seqs.
从函数式编程的角度来看,枚举器实际上就是一个折叠函数。类在面向对象的数据结构库中实现 Enumerable 接口,而类型在函数式数据结构库中带有折叠函数。
Stream
是一个有点古怪的命令式惰性列表(命令式是因为读取元素是破坏性的)。 CamlP5 附带一个功能性惰性列表库Fstream
。 这个已经引用的线程提供了一些替代方案。An enumerator, seen from a functional programming angle, is exactly a
fold
function. Where a class would implement anEnumerable
interface in an object-oriented data structures library, a type comes with afold
function in a functional data structure library.Stream
is a slightly quirky imperative lazy list (imperative in that reading an element is destructive). CamlP5 comes with a functional lazy list library,Fstream
. This already cited thread offers some alternatives.您似乎正在寻找类似“惰性列表”之类的东西。
看看这个SO问题
It seems you are looking for something like Lazy lists.
Check out this SO question
提到的电池库还提供了 (--) 运算符:
在遍历项目之前不会评估枚举,因此它提供了类似于您的第二个请求的功能。请注意,电池的
枚举
是可变的。理想情况下,还应该有一个惰性列表实现,所有数据结构都可以相互转换,但这项工作尚未完成。The Batteries library mentioned also provides the (--) operator:
The enum is not evaluated until you traverse the items, so it provides a feature similar to your second request. Just beware that Batteries'
enum
s are mutable. Ideally, there would also be a lazy list implementation that all data structures could be converted to/from, but that work has not been done yet.