在Clojure中,如何使用iterate函数构建惰性序列?

8

clojure 文档 给出了以下示例:

(take 10 (iterate (partial + 2) 0))

(def powers-of-two (iterate (partial * 2) 1))
(take 10 powers-of-two)

(def fib (map first (iterate (fn [[a b]] [b (+ a b)]) [1 1])))
(take 10 fib)

任何人都能更详细地解释Clojure的iterate函数的语法吗?我对所有用法都感到很困惑。为什么(fn [[a b]] [b (+ a b)])中有两个括号?
另一个例子可以在这里找到:
(defn iter [[x y]]
  (vector y (+ x y)))

(nth (iterate iter [0 1]) 10000)
1个回答

17

iterate 接受一个函数 f 和一个初始值 x,并生成一个惰性序列。序列的第一个元素是 x。每个随后的元素都通过调用 f 与先前的元素计算得出。

示例 1:

(iterate (partial + 2) 0)

这会生成一个从0开始的序列,其中每个元素都是前一个元素加2。即:

0
(+ 2 0) ; => 2
(+ 2 2) ; => 4
(+ 2 4) ; => 6
; etc

在生成下一个元素时,将 seq 中的每个元素传递给 (partial + 2)

例子2:

(iterate (partial * 2) 1)

这将生成一个序列,从1开始,每个元素都是前一个元素乘以2。即:

1
(* 2 1) ; => 2
(* 2 2) ; => 4
(* 2 4) ; => 8
(* 2 8) ; => 16
; etc

再次,您可以看到每个元素如何为下一个元素的生成做出贡献。

示例3:

(iterate (fn [[a b]] [b (+ a b)]) [1 1])

首先,(fn [[a b]] ...) 是将一个值解构成多个部分的方法。在这种情况下,该函数接受一个两元素向量并将其解包到本地变量 ab 中。

该函数返回一个包含 bab 的和(即前一对中的第二个值和前一对中两个值的和)的两元素向量。

考虑到这一点,此 iterate 调用会生成:

[1 1]
[1 (+ 1 1)] ; => [1 2]
[2 (+ 1 2)] ; => [2 3]
[3 (+ 2 3)] ; => [3 5]
[5 (+ 3 5)] ; => [5 8]
; etc

然后 (map first ...) 获取每对中的第一个值,这将给出斐波那契数列。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接