2009-10-27 11 views
8

倍数のシーケンスを表す遅延リストを作成するにはどうすればよいですか?例:Ocaml:遅延リスト

1 2 4 8 16 32 
+1

あなたはレイジーリストの特定の実装を意味するのか、それとも一般的な概念だけを意味しますか?また、実際にはlazy _lists_(値は一度計算されるとメモに記録されます)が必要ですか、ストリームだけが必要ですか(値はメモではなく、したがって一度しか読み取れません)。 –

+0

ストリームを探しています。 –

答えて

9

素晴らしいブログenfranchised心はこのトピックに関する素晴らしい記事があります。

http://enfranchisedmind.com/blog/posts/ocaml-lazy-lists-an-introduction/

ます。また、これに対処するための標準的なライブラリですhttp://batteries.forge.ocamlcore.org/doc.preview%3Abatteries-beta1/html/api/Lazy%5Flist.html

をチェックアウトすることができます。

この質問はまた、この質問に非常に似ています

What OCaml libraries are there for lazy list handling?

+0

最初のリンクはもはや動かず、ホストを移動しましたか? – Oleg

+0

@Olegはドメインの有効期限が切れているようです。これはインターネット上の人生です。この回答はほぼ8歳になりました:) – chollida

+0

バッテリーライブラリに[3種類の多かれ少なかろうとするシーケンスの種類](https://github.com/ocaml-batteries-team/batteries-included/wiki/ListTypes)が追加されました。異なる特性を有する。 – Mars

13

使用ストリーム:カスタムlazy_listタイプを使用

let f x = Stream.from (fun n -> Some (x * int_of_float (2.0 ** float_of_int n))) 

または

let f x = 
    let next = ref x in 
    Stream.from (fun _ -> let y = !next in next := 2 * y ; Some y) 

type 'a lazy_list = 
    | Nil 
    | Cons of 'a * 'a lazy_list lazy_t 
let rec f x = lazy (Cons (x, f (2*x))) 
1

あなたが手でそれをしたい場合は、私はあなたが主なオプションに持っていると言うだろう:ephemientは(彼の解決策は少し壊れている除く)が言ったように

  • は、カスタムlazy_listタイプを使用します:

    type 'a lazy_list = 
        | Nil 
        | Cons of 'a * 'a lazy_list 
    
    let head = function 
        | Nil -> failwith "Cannot extract head of empty list" 
        | Cons (h, _) -> h 
    
    let tail = function 
        | Nil -> failwith "Cannot extract tail of empty list" 
        | Cons (_, t) -> t 
    
  • は、サンクの種類を使用します(それをサポートしていない言語で遅延評価を実装するために使用されるものなど)。リストを関数unit -> 'aとして定義し、現在の要素から次の要素を取得する方法を示します(ストリームを使用する必要はありません)。

    0 
    1 
    2 
    
+0

私の 'lazy_list'のどの部分が壊れていますか?私はそれを書いていたときにテストしなかったし、OCamlよりもHaskellとSMLをよく知っているが、OCaml 3.11.1でこれをテストした。ストリームは主に、OPがストリームを求める質問にコメントを追加したためです。 – ephemient

+0

Woops、そうだよ、本当に*本当に*間違っていた...さらに、ストリームの使用に関するコメントもなかった。次回は眼鏡をかけます:s。 – jdb

3

:たとえば、すべての自然な整数のリストを定義するために、あなたは

print_int (naturals()); 
print_int (naturals()); 
print_int (naturals()) 

を行う場合は、次のような出力が得られます

let make_lazy_list initial next = 
    let lazy_list current() = 
     let result = !current in 
     current := (next !current); result 
    in lazy_list (ref initial) 

let naturals = make_lazy_list 0 (function i -> i + 1) 

ザ・操作を行うことができますまた、私のOCaml Network Application Environment Core Foundationには、Cf_seqという遅延リストモジュールがあります。実際には、機能的なデータ構造の全体を書きました。 2節のBSDライセンスの下で利用可能です。楽しい。

更新:コードの名前が「Oni」に変更され、BitBucketでホストされています。また、GODIパッケージを使用することもできます。