clojure中惰性过滤器的实现
在上,clojure中惰性过滤器的实现,clojure,lazy-sequences,Clojure,Lazy Sequences,在上,过滤器的定义如下: (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
过滤器
的定义如下:
(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))))
递归调用是对
过滤器
,而不是对步骤
重要吗?如果是,原因是什么?它与这里给出的其余代码一起,因为是过滤器
在惰性序列中进行包装。如果step
调用自身,它将一次完成所有过滤,而不是惰性地进行过滤
(更新)如果lazy seq
被添加到step
的主体中,那么step
可以调用自己,并且仍然是懒惰的。这至少可以通过以下两种方式实现:
将整个主体包装在lazy seq
中,并将对filter
的递归调用和对recur
的调用替换为对步骤的调用;注意。在这种情况下,需要命名步骤
函数(通过将let
替换为letfn
,并对语法进行适当更改,或者通过向fn
表单添加名称:(fn步骤…
);然后,lazy seq
将最外层的调用包装到步骤
将是不必要的;此外,在这一点上,您可能根本没有内部助手函数(只需直接在过滤器中使用此方法即可)
将lazy seq
保留在filter
中,并将递归调用包装在step
中(现在将是step
本身),包装在lazy seq
中(保持recur
表单不变)
请注意,clojure.core/filter
具有不同的实现,具有单独的逻辑处理分块序列,并且没有内部帮助函数。在非分块的情况下,它的操作类似于第1节中描述的步骤版本。上面。但是如果我用惰性序列
包裹整个身体,那么重复
就不会在后面了position@tempestadept对,您必须用另一个递归调用替换它。(clojure.core/filter
在非分块的情况下有效地工作。)我编辑了答案以考虑这一点。