我想展现给非FP程序员懒惰序列或懒惰评估的重要性。 我写了这个实施黄金一代的显示概念:
(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
的thunk越来越积累。 但是,如果DO (doall (filter ...
然后我不就能够处理无限序列,即(take 1000 (primes-gen (iterate inc 2)))
将不再工作。
什么是做正确的方式?