Clojureで以下を試してみました。非遅延シーケンスのクラスが返されることを期待しています。
(.getClass (doall (take 3 (repeatedly Rand))))
ただし、これは依然としてclojure.lang.LazySeq
を返します。私の推測では、doall
はシーケンス全体を評価しますが、メモ化にはまだ有用なので元のシーケンスを返します。
では、怠zyなシーケンスから非遅延シーケンスを作成する慣用的な手段は何ですか?
doallで十分です。 seqのタイプがLazySeqであるからといって、評価が保留されているわけではありません。レイジーシーケンスは結果をキャッシュするので、必要なのは、レイジーシーケンスを1回(doallが行うように)歩いてすべて強制的に実行し、それによってレイジーでないようにすることです。 seqはnotコレクション全体を強制的に評価します。
これは、ある程度分類の問題です。 レイジーシーケンスは、シーケンスの一種です asはリスト、ベクター、またはマップです。したがって、答えはもちろん「取得する非遅延シーケンスの種類によって異なります。
次から選択してください:
(doall ... )
(apply list (my-lazy-seq)) OR (into () ...)
(vec (my-lazy-seq))
必要なほとんどのスイートにどんなタイプのシーケンスでも使用できます。
この金持ちの男は彼のclojureを知っているようで、絶対に正しいです。
Buthこのコードスニペットは、例を使用すると、この質問を補足するのに役立つかもしれません。
=> (realized? (take 3 (repeatedly Rand)))
false
=> (realized? (doall (take 3 (repeatedly Rand))))
true
確かにtypeは変更されていませんが、realizationは変更されています
これにつまずいた blogdoall
が再帰的ではないという投稿。そのために、私は投稿の最初のコメントがトリックをしたことを発見しました。以下の線に沿ったもの:
(use 'closure.walk)
(postwalk identity nested-lazy-thing)
これは、map
の入れ子になったアプリケーションのいくつかの評価を強制してエラー条件を強制したい単体テストで役立ちました。
(.getClass (into '() (take 3 (repeatedly Rand))))