我只是学习在Clojure中使用延迟序列,我不确定我在下面的代码中做错了什么:
(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)
求和的数字不应大于100
,那么导致整数溢出的原因是什么?
答案 0 :(得分:5)
从clojure 1.3.0开始,数字不会自动提升为bigInt / bigDecimal。
修复此用途+'
而不是
你的第100个纤维蛋白数对于整数来说太大了
user> (nth (fib) 100)
354224848179261915075N
答案 1 :(得分:5)
过滤无限seq会产生无限seq并减少此值会导致过滤器在谓词停止返回true后仍继续寻找另一个匹配项。
将filter
替换为take-while
。 (fib)
生成的无限序列将导致filter
永远运行,但在此之前,由于您遇到的ArithmeticException
,它会中断。在take-while
谓词评估为false后,(fn [x] (< x n))
将停止对列表的进一步评估。
(defn up-to [n seqn]
(take-while (fn [x] (< x n)) seqn))
(sum (up-to 100 (fib))) ;; => 232