为什么Clojure的反向函数返回非惰性序列?

时间:2011-11-20 22:09:38

标签: clojure lisp lazy-evaluation

为什么Clojure的反向函数的设计者决定返回的序列不是懒惰的? Clojure通常会接受懒惰的序列。

3 个答案:

答案 0 :(得分:11)

当然,这是因为根据定义,为了反转一个序列,你必须知道另一端是什么,以便返回将成为反向集合中第一个项目的内容。

因此,序列必须是有限的,你必须对它进行评估才能使用它的结尾。

附录:

反向作为无限序列没有意义,(尽管可以说无限序列并不总是懒惰的先决条件)。

如果您要撤消一个集合,那么您已经将其加载到内存中;它不需要计算。

答案 1 :(得分:8)

rseq返回以相反顺序遍历集合的seq。它仅适用于可逆集合,例如vector,sorted-set和sorted-map。

reverse将反转任何有限的seq,但这样做的代价是遍历所有项目并将它们分配到列表中。它实现为(reduce conj () coll)。这显然不是懒惰。

答案 2 :(得分:1)

Scott's answer

之后

reverse函数逐个元素地减少其序列参数。如果我们可以使reverse真正变得懒惰,我们可以对其他减少做同样的事情。所以让我们写一个reduce的懒惰版本:

(defn lazy-reduce [f init coll]
  (lazy-seq
   (if (seq coll)
     (lazy-reduce f (f init (first coll)) (rest coll))
     init)))

顺便提一下,这仅适用于序列。

但它有效:

(lazy-reduce conj () (range 5))
; (4 3 2 1 0)

如果我们从未触及结果,则不计算任何内容。我们赢了。但是,只要我们触摸第一个元素,就会实现整个序列,解开就像用针脚掉线编织一样。