2014-01-23 5 views
5

Я написал функцию типа Сита в Clojure на основе Sieve of Eratosthenes ..... и наткнулся на ошибку со списками пар: ClassCastException clojure.lang.Cons нельзя отбросить java.lang.Number   clojure.lang.Numbers.remainder (Numbers.java:171)Коллекция пар в Clojure с использованием минусов


(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) 

Однако изменение маркировки стиля, отказ от недостатков и использования Призывание или векторных пар вместо этого, оба solv ошибка.

Еще я ищу хорошее объяснение ошибки ....

+1

Вы не можете ожидать ответа, если вы не размещаете всю соответствующий код. Там нет остаточного звонка ... ясно, что 'mark-divisors' отсутствует. –

+0

Вы правы - thaks – FredAKA

+0

в какой-то момент делит? функция получает 3 и (4 ложных) аргумента. Второй аргумент arg не может быть добавлен к номеру – edbond

ответ

6

Проблема заключается в том, что list? проверка терпит неудачу на последовательности, построенной с cons, как показано ниже:

(list? (conj() 1)) ;=> true 
(list? (cons 1())) ; => false 

Вы можете переключаться ваш звонок до list? на звонок до seq?, и он должен работать.

Для получения подробной информации о том, почему это так я рекомендую прочитать этот ответ: Clojure: cons(seq) vs. conj(list)

+0

Отлично. Спасибо за решение. Забавный список? не обсуждается в чтении ref. Ваш пример должен быть включен там, и http://clojuredocs.org/clojure_core/clojure.core/list_q – FredAKA

+0

Я думаю, что ошибка в дизайне имеет (список? (Cons 1())); => false – FredAKA

+0

@FredAKA, вам нужно учитывать, что существует различие между списком и секцией в Clojure. – ponzao

Смежные вопросы