0

http://clojure.org/lazy上,filter是这样定义的:

(defn filter
  "Returns a lazy sequence of the items in coll for which
  (pred item) returns true. pred must be free of side-effects."
  [pred coll]
  (let [step (fn [p c]
                 (when-let [s (seq c)]
                   (if (p (first s))
                     (cons (first s) (filter p (rest s)))
                     (recur p (rest s)))))]
    (lazy-seq (step pred coll))))

递归调用是 tofilter而不是 to重要step吗?如果是,为什么?

4

1 回答 1

1

它与此处给出的其余代码一起使用,因为它是filterlazy-seq. 如果step调用它自己,它将一次完成所有过滤而不是懒惰。

(已更新。)如果lazy-seq被添加到step' 的主体,step则可以调用自身并且仍然是懒惰的。这至少可以通过以下两种方式来实现:

  1. 通过将整个主体包裹起来lazy-seq并替换递归调用 tofilterrecurwith 调用 to step;注意。在这种情况下,step需要为函数命名(通过用适当的语法更改替换,或者在表单中添加let名称:);包装最外层的调用将是不必要的;此外,此时您可能根本没有内部辅助函数(直接使用这种方法);letfnfn(fn step ...)lazy-seqstepfilter

  2. 通过将 in 留lazy-seq在原filter处并将递归调用step(现在将对其step自身)包装在lazy-seqrecur形式保持不变)中。

请注意,它clojure.core/filter具有不同的实现,具有单独的逻辑处理分块序列并且没有内部辅助函数。在非分块情况下,它的操作方式与step上面 1. 中描述的版本类似。

于 2013-10-01T06:58:05.397 回答