2010-05-31 38 views
17

我期待通过一些例子斐波那契序列的Clojure代码:clojure中的lazy-seq有什么意义?

(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一起工作,因为我以前在范围内绑定了fibs。

回答

16

lazy-seq[1 2]是不需要的,但并不真正伤害。

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

7

据我了解(我承认仍然是一个相对较新的Clojure的!),如果你尝试以下方法:

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

然后,它不会工作,因为小谎尚未绑定和因此后面两个引用失败。

然而,你给出的懒惰版本将会起作用,因为对于fibs的引用只有在消耗序列后才真正解决 - 并且fibs已经被成功定义为lazy sequence。