我已经实现了一个惰性素数生成器(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在第一个问题中指出错误。如果从下一个中删除括号,则可以正常工作。
答案 0 :(得分:0)
(next)
周围有一个额外的括号:next
然后被称为函数IFn
,尽管next
是Long
...
对于第二个问题,clojure doc中的las示例详细介绍了两种解决方案之间的区别。
大致(cons n (lazy-seq ...))
将始终评估n
,即使它未被消费,(lazy-seq (cons n ...))
也完全是懒惰的。如果n
不仅仅是一个数字,而是一些可能是计算密集型的函数,那也很重要。