如何将懒惰序列转换为非懒惰的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强制错误条件。