我正在基于Eratosthenes的Sieve在Clojure中编写一个Sieve类型的函数.....并且遇到了对列表的错误:ClassCastException clojure.lang.Cons无法强制转换为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)))))
Run Code Online (Sandbox Code Playgroud)
;(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)
Run Code Online (Sandbox Code Playgroud)
但是,改变标记样式,放弃缺点并使用conj或vector对,都解决了错误.
我仍然在寻找错误的一个很好的解释....
问题是list?在使用cons如下所示构建的序列上检查失败:
(list? (conj () 1)) ;=> true
(list? (cons 1 ())) ; => false
Run Code Online (Sandbox Code Playgroud)
您可以将呼叫切换list?到呼叫seq?,它应该可以工作.
有关为什么会这样的详细信息,我建议您阅读以下答案:Clojure:cons(seq)vs conj(list)
| 归档时间: |
|
| 查看次数: |
253 次 |
| 最近记录: |