“迭代提供了无限的惰性序列”
(= (range 20) (take 20 (iterate inc 0)))
所以我的问题是为什么它从 0 而不是 1 开始?如何理解这里的懒惰?
“迭代提供了无限的惰性序列”
(= (range 20) (take 20 (iterate inc 0)))
所以我的问题是为什么它从 0 而不是 1 开始?如何理解这里的懒惰?
公案要求迭代从零开始,因为range
默认情况下从 0 开始,这使得声明看起来很漂亮。在编程中从 0 而不是 1 开始计数是典型且有用的。但是,可以编写公案以从 1 开始(或任何其他数字)
(= (range 1 21) (take 20 (iterate inc 1)))
这是迭代的定义方式
user=> (source iterate)
(defn iterate
"Returns a lazy sequence of x, (f x), (f (f x)) etc. f must be free of side-effects"
{:added "1.0"
:static true}
[f x] (cons x (lazy-seq (iterate f (f x)))))
所以,这就是(iterate inc 0)
最初的样子
(cons 0, (lazy-seq (iterate inc (inc 0))))
现在,当位置 1(即从我们从 0 开始计数的第二个位置)处的特殊惰性序列元素第一次被访问时,它实际上被它的扩展替换。
-- (iterate inc (inc 0))
-> (iterate inc 1)
-> (cons 1, (lazy-seq (iterate inc (inc 1))))
所以,序列现在看起来像
-- (cons 0, (lazy-seq (iterate inc (inc 0))))
-> (cons 0, (cons 1 (lazy-seq (iterate inc (inc 1)))))
当位置 2 的特殊惰性序列元素第一次被访问时,它实际上被它的扩展替换。
-- (iterate inc (inc 1))
-> (iterate inc 2)
-> (cons 2, (lazy-seq (iterate inc (inc 2))))
所以,序列现在看起来像
-- (cons 0, (cons 1 (lazy-seq (iterate inc (inc 1)))))
-> (cons 0, (cons 1, (cons 2, (lazy-seq (iterate inc (inc 2))))))
需要注意的一些后果,但作为新用户通常无需担心
with-
块内返回。(def numbers (iterate inc 0))
并实现它们中的一堆,它们将保留在内存中。如果这是一个问题,请避免“抱头”。clojure.core/iterate有两个参数:
fn
应用于序列中的最后一个元素。应用时,它应该产生序列中的下一个元素
序列的初始值
(iterate inc 0)
具有0
作为序列的初始元素。
(take 1 (iterate inc 0)) ;; (0)