我在Clojure中尝试了以下内容,期望返回非惰性序列的类:
(.getClass (doall (take 3 (repeatedly rand))))
但是,这仍然会返回clojure.lang.LazySeq
。我的猜测是doall
会对整个序列进行评估,但会返回原始序列,因为它仍然可用于记忆。
那么从惰性序列中创建非惰性序列的惯用方法是什么?
答案 0 :(得分:149)
doall 就是您所需要的。仅仅因为seq具有类型LazySeq并不意味着它具有待定的评估。懒惰的seqs缓存它们的结果,所以你需要做的就是走懒惰的seq一次(就像doall一样)以强制它全部,从而使它变得非懒惰。 seq 不强制要对整个集合进行评估。
答案 1 :(得分:63)
这在某种程度上是分类学的问题。 懒惰序列只是一种类型的序列,就像列表,向量或映射一样。所以答案当然是“这取决于你想得到什么类型的非懒惰序列:
请选择:
(doall ... )
(apply list (my-lazy-seq)) OR (into () ...)
(vec (my-lazy-seq))
您可以根据自己的需要选择任何类型的序列。
答案 2 :(得分:21)
这个富家似乎知道他的咒语,绝对是对的 但是我认为这个代码片段,使用你的例子,可能是这个问题的有用补充:
=> (realized? (take 3 (repeatedly rand)))
false
=> (realized? (doall (take 3 (repeatedly rand))))
true
确实类型没有改变,但实现有
答案 3 :(得分:7)
我偶然发现了blog这篇关于doall
没有递归的帖子。为此,我发现帖子中的第一条评论就是诀窍。有点像:
(use 'closure.walk)
(postwalk identity nested-lazy-thing)
我发现这在单元测试中非常有用,我想强制评估map
的一些嵌套应用程序以强制出错。
答案 4 :(得分:5)
(.getClass (into '() (take 3 (repeatedly rand))))