17

我正在查看一些示例斐波那契序列 clojure 代码:

 (def fibs (lazy-cat [1 2] (map + fibs (rest fibs))))

我大致了解发生了什么,但不明白lazy-cat. 我知道这lazy-cat是一个宏,它正在翻译成这样的东西:

(def fibs (concat (lazy-seq [1 2]) (lazy-seq (map + fibs (rest fibs))))) 

究竟在lazy-seq完成什么?即使没有 ,它仍然会被懒惰地评估lazy-seq?这是否严格用于缓存目的?

编辑:感谢您的回答。我的困惑是它可以与concatREPL 中的普通文本一起使用,因为我之前在范围内绑定了 fibs。

4

2 回答 2

16

lazy-seqon[1 2]不是必需的,但并没有真正伤害。

lazy-seq(map + fibs (rest fibs))必不可少的;没有它,函数调用将在fibs绑定到一个值之前进行评估,这将导致异常。通过将其包装在 中lazy-seq,调用将被推迟到需要该值时,并且fibs此时将具有一个值。

于 2010-05-31T17:07:14.137 回答
7

据我了解(我承认仍然是 Clojure 的新手!),如果您尝试以下操作:

(def fibs (concat [1 2] (map + fibs (rest fibs))))

然后它将不起作用,因为 fibs 尚未绑定,因此后来对它的两次引用失败。

但是,您提供的惰性版本将起作用,因为对 fibs 的引用仅在稍后使用序列时才真正解决 - 并且此时 fibs 已成功定义为惰性序列。

于 2010-05-31T17:03:14.803 回答