这有效:
(defn tri*
([] (tri* 0 1))
([sum n]
(let [new-sum (+ sum n)]
(cons new-sum (lazy-seq (tri* new-sum (+ n 1)))))))
但当我在其中使用recur
时,我会得到CompilerException
:
不匹配的参数计数重复,预期0参数,得到:2
(defn tri*
([] (tri* 0 1))
([sum n]
(let [new-sum (+ sum n)]
(cons new-sum (lazy-seq (recur new-sum (+ n 1)))))))
答案 0 :(得分:6)
lazy-seq
是一个宏,它扩展为涉及零arg thunk的代码,可以在实现序列时调用。您可以通过执行
recur
表单被捕获为此thunk的主体
(macroexpand '(lazy-seq (recur new-sum (+ n 1))))
获取
(new clojure.lang.LazySeq (fn* [] (recur new-sum (+ n 1))))
表明recur
的目标是thunk,而不是tri*
。
考虑所有这一切的另一种方式是,tri*
的原始调用早已完成(并且在Cons
时返回包含LazySeq
rest对象的recur
对象1}}将被“评估”。
您的tri*
的第一个版本很好,因为对tri*
的递归调用不会增加堆栈,而只是创建一组新的Cons
/ {{ 1}}对象。