I’m just learning to use lazy sequences in Clojure, and I’m not sure what I’m doing wrong in the following code:
(defn sum [seqn]
(reduce + seqn))
(defn fib
([] (concat [0 1] (fib 0 1)))
([a b] (lazy-seq (cons (+ a b) (fib b (+ a b))))))
(defn up-to [n seqn]
(filter (fn [x] (< x n)) seqn))
(sum (up-to 100 (fib))) => ArithmeticException integer overflow clojure.lang.Numbers.throwIntOverflow (Numbers.java:1388)
The numbers being summed shouldn’t be larger than 100, so what is causing the integer overflow?
Filtering an infinite seq produces an infinite seq and reducing over this causes filter to keep looking for another matching item even after the predicate stops returning true.
Replace
filterwithtake-while. The infinite sequence generated by(fib)will causefilterto run forever, but before that it will break due to theArithmeticExceptionyou’re experiencing.take-whilewill stop further evaluation of the list after the(fn [x] (< x n))predicate evaluates to false.