我正在查看一些示例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
,它仍会被懒惰地评估?这是否严格用于缓存目的?
concat
一起使用,因为我之前已经在范围内绑定了fib。
答案 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定义为延迟序列。