使用无限流生成前10个斐波纳契数

时间:2016-07-02 19:05:29

标签: clojure fibonacci lazy-sequences

我试图获得前10个斐波那契数字如下:

(take 10 (fn fibgen [a b] (cons a (fibgen b (+ a b))) 0 1))

这个想法是fibgen创建了一个懒惰的序列(一个无限的流)。不幸的是,这会产生以下错误:

  

IllegalArgumentException不知道如何创建ISeq:
用户$ eval10144 $ fibgen__10145 clojure.lang.RT.seqFrom(RT.java:528)

如何解决这个问题?

1 个答案:

答案 0 :(得分:3)

我认为你刚刚写了一个错字。以下是fibgen函数重新格式化的内容:

(fn fibgen [a b]
  (cons a (fibgen b (+ a b)))
  0
  1)

此函数实现从ab开始的整个Fibonacci序列,然后返回1.您要做的是定义一个返回序列的函数,调用它用0和1,然后从该序列中取出前十项:

(take 10 ((fn fibgen [a b] (cons a (fibgen b (+ a b)))) 0 1))

如果你运行它,你会得到ArithmeticException的整数溢出,因为Fibonacci序列中的数字很快就会离开64位整数的范围。您可以使用+'修补此问题:

(take 10 ((fn fibgen [a b] (cons a (fibgen b (+' a b)))) 0 1))

由于Clojure不是懒惰的,这将尝试实现整个 Fibonacci序列,这将导致StackOverflowError。尽管Clojure本身并不懒惰,但你可以创建一个lazy sequence,在这种情况下它会产生基本相同的效果:

(take 10 ((fn fibgen [a b] (lazy-seq (cons a (fibgen b (+' a b))))) 0 1))
;;=> (0 1 1 2 3 5 8 13 21 34)