我在 Clojure 中尝试了以下操作,期望返回非惰性序列的类:
(.getClass (doall (take 3 (repeatedly rand))))
但是,这仍然返回clojure.lang.LazySeq。我的猜测是,它doall确实评估了整个序列,但返回了原始序列,因为它仍然对记忆有用。
那么从惰性序列创建非惰性序列的惯用方法是什么?
我在 Clojure 中尝试了以下操作,期望返回非惰性序列的类:
(.getClass (doall (take 3 (repeatedly rand))))
但是,这仍然返回clojure.lang.LazySeq。我的猜测是,它doall确实评估了整个序列,但返回了原始序列,因为它仍然对记忆有用。
那么从惰性序列创建非惰性序列的惯用方法是什么?
doall是你所需要的全部。仅仅因为seqhas 类型LazySeq并不意味着它有待评估。Lazyseq会缓存它们的结果,因此您需要做的就是将lazy 遍历seq一次(就像doall这样做一样)以强制执行所有操作,从而使其成为非懒惰的。seq不强制评估整个集合。
这在某种程度上是分类学的问题。惰性序列只是列表、向量或映射的一种序列。所以答案当然是“这取决于你想要得到什么类型的非惰性序列:
你可以选择:
(doall ... ) (apply list (my-lazy-seq)) OR (into () ...) (vec (my-lazy-seq)) 您可以拥有最适合您需要的任何类型的序列。
这个有钱的家伙似乎知道他的clojure,而且是绝对正确的。
但我认为这个代码片段,使用你的例子,可能是对这个问题的有用补充:
=> (realized? (take 3 (repeatedly rand)))
false
=> (realized? (doall (take 3 (repeatedly rand))))
true
确实类型没有改变,但实现有
我偶然发现了这篇关于不递归的博客文章。doall为此,我发现帖子中的第一条评论起到了作用。类似于以下内容:
(use 'clojure.walk)
(postwalk identity nested-lazy-thing)
我发现这在单元测试中很有用,我想强制评估一些嵌套应用程序map以强制出现错误条件。
(.getClass (into '() (take 3 (repeatedly rand))))