Clojure 中惰性素数生成器函数内部的绑定

Bindings inside lazy prime number generator function in Clojure

我已经实现了一个惰性素数生成器(nextprime returns 从传递的数字开始的下一个素数):

(defn allprimes
    ([] (allprimes 2))
    ([x] (lazy-seq (cons (nextprime x) (allprimes (nextprime x))))))

让我们假设 nextprime 是一个代价高昂的函数,为了不执行它两次,我尝试将它绑定到一个符号:

(defn allprimes
    ([] (allprimes 2))
    ([x] (let [next (nextprime x)]
        (cons next (lazy-seq (allprimes (next)))))))

但这不起作用(java.lang.Long 不能转换为 clojure.lang.IFn)。为什么?

另外,(cons n (lazy-seq ...)) 和 (lazy-seq (cons n ...)) 有区别吗?

编辑:感谢 Kyle 指出第一个问题中的错误。如果从 next 中删除括号,它会起作用。

你在 (next) 周围有额外的括号:next 然后作为函数调用 IFn 尽管 nextLong...

对于你的第二个问题,clojure doc中的las示例详细说明了两种解决方案之间的区别。

大致(cons n (lazy-seq ...))会一直求值n,即使没有消费,(lazy-seq (cons n ...))是完全惰性的。如果 n 不仅仅是一个数字,而是一些可能需要大量计算的函数,这可能很重要。