试图用Clojure以下,期待有类非延迟序列返回:我如何偷懒序列转换为非懒惰Clojure中
(.getClass (doall (take 3 (repeatedly rand))))
然而,这仍然返回clojure.lang.LazySeq
。我的猜测是doall
确实评估整个序列,但返回原始序列,因为它仍然用于记忆。
那么从懒惰创建非惰性序列的惯用方法是什么?
试图用Clojure以下,期待有类非延迟序列返回:我如何偷懒序列转换为非懒惰Clojure中
(.getClass (doall (take 3 (repeatedly rand))))
然而,这仍然返回clojure.lang.LazySeq
。我的猜测是doall
确实评估整个序列,但返回原始序列,因为它仍然用于记忆。
那么从懒惰创建非惰性序列的惯用方法是什么?
doall是你所需要的。仅仅因为seq有类型LazySeq并不意味着它有待评估。懒惰的seqs缓存他们的结果,所以你所需要做的只是一次走懒惰seq(就像doall一样),以强制所有这些,从而使其不会懒惰。 seq确实不是强制对整个集合进行评估。
I'已经将其改为已接受的答案。在相关说明中,通过什么方法可以确定LazySeq是否先前已经过评估? – 2009-10-29 14:16:31
我相信你只是叫'实现?'。 – toofarsideways 2012-02-01 02:40:14
可能应该有一个“实现”操作来匹配'实现?'。 – 2017-02-01 14:07:28
这在某种程度上是一个分类问题。 懒惰序列只是一种类型的序列,因为它是一个列表,向量或映射。因此,答案当然是“这取决于你想要得到什么类型的非懒序列:
(doall ...)
(apply list (my-lazy-seq)) OR (into() ...)
(vec (my-lazy-seq))
您可以拥有最适合您需要的任何类型的序列。
这是最好的答案。 – 2014-07-25 16:20:17
接受的答案在技术上是正确的,但是这个答案对我来说最有用。我试图在vector上映射一个函数,然后将结果吐在一个文件中,甚至在调用doall之后,文件中包含“[email protected]”而不是序列的内容。在返回的值映射上调用vec让我得到了我需要吐出的文件。 – 2015-11-23 23:17:29
@JesseRosalia很高兴知道所有SO中唯一的Rich Hickey响应在技术上是正确的。 ;-) – 2016-03-15 21:02:44
这个有钱人似乎知道他的clojure,是绝对正确的。
Buth我觉得这个代码片段,使用你的榜样,可能是一个有益的补充这样一个问题:
=> (realized? (take 3 (repeatedly rand)))
false
=> (realized? (doall (take 3 (repeatedly rand))))
true
事实上型并没有改变,但实现已经
我这个迷迷糊糊这个blog关于doall
的帖子不是递归的。为此,我发现在帖子中的第一条评论做了诀窍。沿着线的东西:
(use 'closure.walk)
(postwalk identity nested-lazy-thing)
我发现这个有用的单元测试,我想强制的map
一些嵌套应用评估,以迫使一个错误条件。
我很惊讶没有人问你为什么要关注'doall'的返回值的实际类型 – tar 2017-11-01 17:14:57
你可以转换成矢量:'(vec(take 3(repeated rand)))' – Kris 2018-01-23 12:33:50