【问题标题】:Bindings inside lazy prime number generator function in ClojureClojure 中惰性素数生成器函数中的绑定
【发布时间】:2015-02-19 20:22:34
【问题描述】:

我已经实现了一个惰性素数生成器(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 在第一个问题中指出错误。如果括号从 next 中删除,它可以工作。

【问题讨论】:

  • next 在函数位置。尝试删除括号 - (allprimes next)
  • 谢谢,第一个问题已经结束了……我觉得好傻!
  • 还可以看看iterate,它为你构造了一个惰性序列——(def allprimes (iterate nextprime 2))
  • 反正应该是(cons x (allprimes (nextprime x))),不需要let

标签: clojure lazy-evaluation primes seq


【解决方案1】:

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

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

大约(cons n (lazy-seq ...)) 将始终评估n,即使它没有被消耗,而(lazy-seq (cons n ...)) 是完全惰性的。 n 是否不仅仅是一个数字,而是一些计算密集型的函数,这可能很重要。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-31
    • 2010-10-31
    • 1970-01-01
    相关资源
    最近更新 更多