我在 Clojure 中尝试了以下操作,期望返回非惰性序列的类:
(.getClass (doall (take 3 (repeatedly rand))))
但是,这仍然返回clojure.lang.LazySeq
。我的猜测是,它doall
确实评估了整个序列,但返回了原始序列,因为它仍然对记忆有用。
那么从惰性序列创建非惰性序列的惯用方法是什么?
我在 Clojure 中尝试了以下操作,期望返回非惰性序列的类:
(.getClass (doall (take 3 (repeatedly rand))))
但是,这仍然返回clojure.lang.LazySeq
。我的猜测是,它doall
确实评估了整个序列,但返回了原始序列,因为它仍然对记忆有用。
那么从惰性序列创建非惰性序列的惯用方法是什么?
doall
是你所需要的全部。仅仅因为seq
has 类型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))))