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
尽管 next
是 Long
...
对于你的第二个问题,clojure doc中的las示例详细说明了两种解决方案之间的区别。
大致(cons n (lazy-seq ...))
会一直求值n
,即使没有消费,(lazy-seq (cons n ...))
是完全惰性的。如果 n
不仅仅是一个数字,而是一些可能需要大量计算的函数,这可能很重要。
我已经实现了一个惰性素数生成器(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
尽管 next
是 Long
...
对于你的第二个问题,clojure doc中的las示例详细说明了两种解决方案之间的区别。
大致(cons n (lazy-seq ...))
会一直求值n
,即使没有消费,(lazy-seq (cons n ...))
是完全惰性的。如果 n
不仅仅是一个数字,而是一些可能需要大量计算的函数,这可能很重要。