2011-07-05 26 views
6

我使用F#很多。 F#中的所有基本集合都实现IEumberable接口,因此使用F#中的单个Seq模块访问它们是很自然的。这在OCaml中可能吗?IEnumerable <T> in OCaml

另一个问题是F#中的'a seq是懒惰的,例如,我可以创建1一个序列100使用{1..100}以上冗长:

seq { for i=1 to 100 do yield i } 

在OCaml中,我发现自己使用以下两种方法来解决此功能:

  1. 生成一个列表:

    let rec range a b = 
        if a > b then [] 
        else a :: range (a+1) b;; 
    
  2. 或求助于显式递归函数。

第一个生成额外的列表。第二个打破了抽象,因为我需要使用高阶函数(如mapfold)在序列级别上进行操作。

我知道OCaml库有Stream模块。但它的功能似乎非常有限,并不像F#中的'a seq一般。

顺便说一句,我最近使用OCaml玩项目欧拉问题。所以有相当多的序列操作,在一个命令式语言中会是一个复杂的循环体。

+0

对于你的第二个问题,我认为你唯一的选择是创建你自己的功能来做到这一点。虽然你会想确保它是尾递归的,但是。 –

回答

5

这Ocaml库似乎提供你在问什么。我没有使用它。

http://batteries.forge.ocamlcore.org/

结帐这个模块,枚举 http://batteries.forge.ocamlcore.org/doc.preview:batteries-beta1/html/api/Enum.html

我莫名其妙地觉得枚举不是SEQ一个更好的名字。它消除了Seqs上的小写/大写混淆。

+0

谢谢!这是我想要的第二个问题。 –

+0

电池枚举是解决这个问题的标准方法。除非您想使用流解析器,否则不应使用OCaml的Stream模块。电池也有序列和惰性列表,它们有不同的实现和语义。 –

0

电池库还提到提供了( - )运算符:

# 1 -- 100;; 
- : int BatEnum.t = <abstr> 

枚举不计算,直到你穿越的项目,所以它提供了类似于你的第二个请求的功能。只要注意电池'enum s是可变的。理想情况下,还会有一个惰性列表实现,即所有数据结构都可以转换为/从,但该工作尚未完成。

1

从函数式编程角度看,枚举器完全是fold函数。如果一个类将在面向对象的数据结构库中实现接口,那么类型将在函数式数据结构库中提供一个fold函数。

Stream是一个有点古怪的命令懒惰列表(当务之急是阅读一个元素是破坏性的)。CamlP5附带一个功能懒惰列表库,FstreamThis already cited thread offers some alternatives

+0

我不认为“流”是“懒”。对我而言,懒惰不仅意味着点播,而且意味着一旦获得结果就会被记录下来。 –

相关问题