2015-01-30 2 views
1

Я пытаюсь запрограммировать ленивое итерационное первичное сито.Где я теряю ленивость?

Каждая итерация решета представлена ​​

[[primes] (candidates) {priority-map-of-multiples-of-primes}] 

и у меня есть функция, сетчатое следующий кандидат-обновление, что Весело берет решето итерации, проверяет следующий кандидат, и обновляет все три компонента соответственно.

Используется так:

(take 3 (iterate sieve-next-candidate-update [[2] (range 3 13 2) (priority-map 2 2)])) 

получить результаты я ожидаю:

([[2] (3 5 7 9 11) {2 2}] 
[[2 3] (5 7 9 11) {3 3, 2 4}] 
[[2 3 5] (7 9 11) {5 5, 2 6, 3 6}]) 

Однако, когда я запускаю его через уменьшить, чтобы удалить итерации, которые не находят новый премьер, он пытается обработать всю последовательность, но я определяю список первых кандидатов (кажущийся бесконечный цикл, если я использую итерацию).

(take 3 
    (reduce (fn [old-primes-sieves new-sieve] 
      (prn (str "reduce fn called with new sieve" new-sieve)) 
      (if (= (last (first (last old-primes-sieves))) ; I'm aware I don't want last in the final version 
        (last (first new-sieve))) 
       old-primes-sieves 
       (conj old-primes-sieves new-sieve))) 
      [] 
      (iterate sieve-next-candidate-update [[2] (range 3 13 2) (priority-map 2 2)]))) 

выходы

"reduce fn called with new sieve[[2] (3 5 7 9 11) {2 2}]" 
"reduce fn called with new sieve[[2 3] (5 7 9 11) {3 3, 2 4}]" 
"reduce fn called with new sieve[[2 3 5] (7 9 11) {5 5, 2 6, 3 6}]" 
"reduce fn called with new sieve[[2 3 5 7] (9 11) {7 7, 2 8, 3 9, 5 10}]" 
"reduce fn called with new sieve[[2 3 5 7] (11) {3 9, 2 10, 5 10, 7 14}]" 
"reduce fn called with new sieve[[2 3 5 7 11] nil {11 11, 2 12, 3 12, 7 14, 5 15}]" 

, а затем бросает NullPointerException в этом ограниченном случае.

Где я теряю ленивость?

ответ

3

reduce не ленив - он попытается повторить всю бесконечную последовательность (iterate sieve-next-candidate-update [[2] (range 3 13 2) (priority-map 2 2)]). Вместо этого вы можете использовать reductions.

Кстати, хороший пример эффективной последовательности бесконечных простых чисел можно найти в clojure.contribhere.

+0

Как я пропустил это! – status203

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