为什么Clojure的反向函数的设计者决定返回的序列不是懒惰的? Clojure通常会接受懒惰的序列。
答案 0 :(得分:11)
当然,这是因为根据定义,为了反转一个序列,你必须知道另一端是什么,以便返回将成为反向集合中第一个项目的内容。
因此,序列必须是有限的,你必须对它进行评估才能使用它的结尾。
附录:
反向作为无限序列没有意义,(尽管可以说无限序列并不总是懒惰的先决条件)。
如果您要撤消一个集合,那么您已经将其加载到内存中;它不需要计算。
答案 1 :(得分:8)
rseq
返回以相反顺序遍历集合的seq。它仅适用于可逆集合,例如vector,sorted-set和sorted-map。
reverse
将反转任何有限的seq,但这样做的代价是遍历所有项目并将它们分配到列表中。它实现为(reduce conj () coll)
。这显然不是懒惰。
答案 2 :(得分:1)
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)
如果我们从未触及结果,则不计算任何内容。我们赢了。但是,只要我们触摸第一个元素,就会实现整个序列,解开就像用针脚掉线编织一样。