2012-07-08 10 views
5

Clojureの関数なぜlazy関数呼び出しだけで構成されるClojure関数も怠惰ですか?

(reductions + 0 (cycle [1 1 -1])) 

はシーケンス[0 1 2 1 2 3 2 3 4 3 4 5 ...]を生成します。残念ながら、このシーケンスは怠惰ではありません。

cyclereductionsは両方とも遅延型の返り値として記述されていますが、これらの関数の組み合わせが遅延型のシーケンスを返すことも期待していました。なぜそれをしないと、シーケンスを遅く返すためにそれを修正できますか?

同じ問題を示して、より複雑な例:

(reductions (fn [x f] (f x)) 0 (cycle [inc inc dec])) 

(これは私がすべての違いを作る場合には、最後に作業しているしたいバージョンの一種であるので、私は、これを示します)

答えて

9

残念ながら、このシーケンスは怠惰ではありません。

ああ、そうです。我々はすぐにそれはその最初の10個の要素を取ることによって、怠惰であることを確認することができます。

(take 10 (reductions + 0 (cycle [1 1 -1]))) 

は、これは非常に迅速にシーケンスが怠惰であることを証明答えを返します。この関数は怠惰ではなく、無限の順序ですべての要素を実現しようとし、メモリを吹き飛ばしたり、無限ループでハングしたりします。

何が起こるかは、REPLでこのfuncをタイプしていることです。これは、シーケンスを実現することを試みる前に実行しようとしています。

編集:あなたは今まであなたが1をトリガしたり、誤って無限の配列を実現するために試したことが判明した場合stop infinite loopsにこのヒントを使用してください。

+0

ありがとうございました。私はそれを防ぐために(def ...)宣言でシーケンスのエイリアスを試みましたが、もちろん動作しません(今は実現しています)。それを(defn ...)と命名しても問題ありません。 – Confusion

+1

関数が怠惰であるかどうかをより正確に確認するには、関数をラップして実装していますか? 。それがfalseを返す場合、関数は遅延です。 =>(実現?(リダクション+0(サイクル[1 1 -1]))) false – NielsK

+1

'実現? '[]'、 ''(a b c) '、' '(iterate inc 0)'のすべての値に '実現してみましょうか?'と試してみると、私の言いたいことが分かります。 – amalloy

関連する問題