Tim*_*ons 91 clojure lazy-evaluation
我在Clojure中尝试了以下内容,期望返回一个非惰性序列的类:
(.getClass (doall (take 3 (repeatedly rand))))
Run Code Online (Sandbox Code Playgroud)
但是,这仍然会回归clojure.lang.LazySeq
.我的猜测是doall
评估整个序列,但返回原始序列,因为它仍然可用于记忆.
那么从懒惰中创建一个非懒惰序列的惯用手段是什么?
小智 151
你需要的就是doall.仅仅因为seq具有类型LazySeq并不意味着它具有待定的评估.懒惰的seqs缓存它们的结果,所以你需要做的就是走懒惰的seq一次(就像doall一样)以强制它全部,从而使它变得非懒惰.序列并没有强制整个集合进行评估.
Art*_*ldt 66
这在某种程度上是分类学的问题.懒惰序列只是一种类型的序列,如列表,向量或映射.所以答案当然是"这取决于你想得到什么类型的非懒惰序列:
从你的选择:
(doall ... )
(apply list (my-lazy-seq)) OR (into () ...)
(vec (my-lazy-seq))
您可以拥有您需要的大多数套房的任何类型的序列.
Pet*_*ter 21
这个有钱人似乎知道他的咒语,是绝对正确的.
但是我认为这个代码片段,使用你的例子,可能是这个问题的有用补充:
=> (realized? (take 3 (repeatedly rand)))
false
=> (realized? (doall (take 3 (repeatedly rand))))
true
Run Code Online (Sandbox Code Playgroud)
确实类型没有改变,但实现已经
我偶然发现这篇关于不是递归的博客文章doall
.为此,我发现帖子中的第一条评论就是诀窍.有点像:
(use 'closure.walk)
(postwalk identity nested-lazy-thing)
Run Code Online (Sandbox Code Playgroud)
我发现这在单元测试中非常有用,我想强制评估一些嵌套应用程序map
来强制错误条件.
小智 5
(.getClass (into '() (take 3 (repeatedly rand))))
Run Code Online (Sandbox Code Playgroud)