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

时间:2015-02-19 20:22:34

标签: clojure lazy-evaluation primes seq

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

(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在第一个问题中指出错误。如果从下一个中删除括号,则可以正常工作。

1 个答案:

答案 0 :(得分:0)

(next)周围有一个额外的括号:next然后被称为函数IFn,尽管nextLong ...

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

大致(cons n (lazy-seq ...))将始终评估n,即使它未被消费,(lazy-seq (cons n ...))也完全是懒惰的。如果n不仅仅是一个数字,而是一些可能是计算密集型的函数,那也很重要。