Я пытаюсь показать важность ленивых последовательностей или ленивую оценку программистам, не относящимся к FP. Я написал это реализация простого поколения, чтобы показать концепцию:lazy-seq и переполнение стека для бесконечных последовательностей
(defn primes-gen [sieve]
(if-not (empty? sieve)
(let [prime (first sieve)]
(cons prime
(lazy-seq (primes-gen
(filter (fn [x]
(not= 0 (mod x prime)))
(rest sieve))))))))
;;;;; --------- TO SHOW ABOUT THE LAZY-THINGS
;; (take 400 (primes-gen (iterate inc 2)))
;; (take 400 (primes-gen (range 2 1000000000000N)))
Однако, я получаю стеку переполнения исключения, если я давать какое-либо большее значение take
.
Стек:
user> (pst)
StackOverflowError
clojure.core/range/fn--4269 (core.clj:2664)
clojure.lang.LazySeq.sval (LazySeq.java:42)
clojure.lang.LazySeq.seq (LazySeq.java:60)
clojure.lang.RT.seq (RT.java:484)
clojure.core/seq (core.clj:133)
clojure.core/filter/fn--4226 (core.clj:2523)
clojure.lang.LazySeq.sval (LazySeq.java:42)
clojure.lang.LazySeq.seq (LazySeq.java:60)
clojure.lang.RT.seq (RT.java:484)
clojure.core/seq (core.clj:133)
кажется, что filter
санки становятся накопили. Но если делать (doall (filter ...
, то я не смог обработать бесконечные последовательности, то есть (take 1000 (primes-gen (iterate inc 2)))
больше не работал.
Каков правильный путь?
Малый пункт: предпочитают '(если (далее сито) ...)' в '(если-нет (пустое сито) ...?)'. – Thumbnail
@amalloy отмеченный вопрос вовсе не дублируется этой: он имеет дело с конечными последовательностями, в то время как этот конкретно задает вопрос о * бесконечных *. Готов к открытию снова, надеюсь, вы тоже. –
@WillNess Согласен. Это одна и та же основная проблема, но ответы на вопрос, который я закрыл, как дубликат, не работают, когда вам нужно работать для бесконечного вывода. Ссылка для будущих зрителей: [Рекурсивная функция, вызывающая переполнение стека] (http://stackoverflow.com/q/2946764/625403) не является дубликатом, как я думал. – amalloy