在clojure中懒惰的问题是什么?

时间:2010-05-31 15:59:48

标签: clojure lazy-evaluation fibonacci infinite-sequence

我正在查看一些示例Fibonacci序列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,它仍会被懒惰地评估?这是否严格用于缓存目的?

编辑:谢谢你的回答。令我感到困惑的是,它与REPL中的普通concat一起使用,因为我之前已经在范围内绑定了fib。

2 个答案:

答案 0 :(得分:16)

lazy-seq [1 2]不需要,但不会真的受伤。

lazy-seq (map + fibs (rest fibs))是至关重要的;如果没有它,将在fibs绑定到值之前评估函数调用,这将导致异常。通过将其包装在lazy-seq中,调用将推迟到需要该值时,fibs将在该点处具有值。

答案 1 :(得分:7)

据我了解(我承认仍然是Clojure的相对新人!),如果您尝试以下内容:

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

然后它将无法工作,因为fibs尚未绑定,因此后来对它的两个引用失败。

你提供的懒惰版本将起作用,因为对fibs的引用实际上只是在序列被消耗的时候才被解析 - 并且到目前为止已经成功地将fibs定义为延迟序列。