【发布时间】:2014-02-14 15:09:44
【问题描述】:
我在 Clojure 中基于 Eratosthenes 的 Sieve 编写了一个 Sieve 类型的函数.....并且遇到了对列表的错误:ClassCastException clojure.lang.Cons cannot be cast to java.lang.Number clojure。 lang.Numbers.remainder(Numbers.java:171)
(defn mark-true [n]
(cons n '(true)))
(defn unmarked? [ns]
(not (list? ns)))
(defn divides? [m n]
(if (= (mod n m) 0)
true
false ))
(defn mark-divisors [n ns]
(cond
(empty? ns) '()
(and (unmarked? (first ns)) (divides? n (first ns)))
(cons (cons (first ns) '(false)) (mark-divisors n (rest ns)))
:else (cons (first ns) (mark-divisors n (rest ns)))))
(defn eratosthenes [ns]
(cond
(empty? ns) '()
(unmarked? (first ns))
(cons (mark-true (first ns))
(eratosthenes (mark-divisors (first ns) (rest ns))))
:else (cons (first ns) (eratosthenes (rest ns)))))
;(eratosthenes (list 2 3 4 5 6))
;=> ClassCastException clojure.lang.Cons cannot be cast to java.lang.Number clojure.lang.Numbers.remainder (Numbers.java:171)
但是,更改标记样式,放弃 cons 并改用 conj 或向量对,都解决了错误。
我仍在寻找错误的良好解释....
【问题讨论】:
-
如果您不发布所有相关代码,您将无法获得答案。那里没有剩余的电话......显然
mark-divisors不见了。 -
你是对的 - 谢谢
-
在某些时候分裂?函数接收 3 和 (4 false) 参数。第二个参数不能转换为数字
-
为什么使用不同的制作方式如 (defn mark-true [n] (conj '(true) n)) 会有所作为?