2011-07-05 27 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

我不認爲「流」是「懶」。對我而言,懶惰不僅意味着點播,而且意味着一旦獲得結果就會被記錄下來。 –

相關問題