101

非遅延シーケンスのクラスが返されることを期待して、Clojureで次のことを試しました。

(.getClass (doall (take 3 (repeatedly rand))))

ただし、これはまだ を返しますclojure.lang.LazySeq。私の推測ではdoall、シーケンス全体を評価しますが、元のシーケンスはメモ化に役立つため、元のシーケンスを返します。

では、遅延シーケンスから非遅延シーケンスを作成する慣用的な手段は何ですか?

4

5 に答える 5

170

doallは、あなたが必要とすることすべてです。seqhasタイプであるからといって、LazySeq評価が保留されているとは限りません。レイジーseqは結果をキャッシュするので、すべてを強制するためにレイジーseqを1回(実行するように)歩くだけで、レイジーではなくなります。コレクション全体を強制的に評価することはありません。doallseq

于 2009-10-29T10:41:28.220 に答える
79

これはある程度、分類学の問題です。遅延シーケンスは、リスト、ベクター、またはマップと同様に、シーケンスの 1 つのタイプにすぎません。したがって、答えはもちろん「取得したい非遅延シーケンスのタイプによって異なります。以下
から選択してください。

  • 元怠惰な (完全に評価された) 怠惰なシーケンス (doall ... )
  • 順次アクセスのリスト (apply list (my-lazy-seq)) OR (into () ...)
  • 後でランダム アクセスするためのベクトル(vec (my-lazy-seq))
  • 特別な目的がある場合はマップまたはセット。

ニーズに最も適したタイプのシーケンスを使用できます。

于 2009-10-29T17:10:29.467 に答える
22

この金持ちの男は自分のクロージュアを知っているようで、絶対に正しい。
しかし、あなたの例を使用したこのコードスニペットは、この質問を補完するのに役立つと思います:

=> (realized? (take 3 (repeatedly rand))) 
false
=> (realized? (doall (take 3 (repeatedly rand)))) 
true

確かにタイプは変わっていませんが、実現は変わっています

于 2013-09-06T09:07:24.837 に答える
5
(.getClass (into '() (take 3 (repeatedly rand))))
于 2009-10-29T16:03:18.887 に答える