如何将懒惰序列转换为非懒惰的Clojure
我在Clojure中尝试了以下方法,期望返回一个非惰性序列的类:
(.getClass (doall (take 3 (repeatedly rand))))
但是,这仍然返回clojure.lang.LazySeq
。 我的猜测是, doall
确实评估整个序列,但返回原始序列,因为它对memoization仍然有用。
那么从懒惰创build一个非懒惰序列的惯用手段是什么?
doall是你所需要的。 只是因为seq有typesLazySeq并不意味着它有待评估。 懒惰的seqscaching他们的结果,所以你所需要做的就是遍历懒惰的seq(像doall一样)来强制这一切,从而使其非懒惰。 seq并不强迫整个收集进行评估。
这在某种程度上是一个分类问题。 一个懒惰的序列只是一个序列types,就像一个列表,向量或映射一样。 所以答案当然是“它取决于你想得到什么types的非延迟序列:
从您的select:
- 一个前懒惰(充分评估)懒惰序列
(doall ... )
- 顺序访问
(apply list (my-lazy-seq)) OR (into () ...)
- 一个随机访问的vector
(vec (my-lazy-seq))
- 一张地图或一套如果你有一些特殊的目的。
你可以有任何types的顺序最符合你的需求。
这个有钱人似乎知道他的clojure,是绝对正确的。
但是,我认为这个代码片断,使用你的例子,可能是这个问题的有益补充:
=> (realized? (take 3 (repeatedly rand))) false => (realized? (doall (take 3 (repeatedly rand)))) true
确实types没有改变,但实现了
(.getClass (into '() (take 3 (repeatedly rand))))
我偶然发现这个博客文章关于doall
不recursion。 为此,我发现在post中的第一个评论做了伎俩。 有些东西是:
(use 'closure.walk) (postwalk identity nested-lazy-thing)
我发现这有用的unit testing,我想强制评估一些嵌套的应用程序的map
强制错误条件。