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

Clojure 使用无限流生成前10个斐波那契数,clojure,fibonacci,lazy-sequences,Clojure,Fibonacci,Lazy Sequences,我试图获得前10个斐波那契数,如下所示: (take 10 (fn fibgen [a b] (cons a (fibgen b (+ a b))) 0 1)) 其思想是,fibgen创建一个惰性序列(无限流)。不幸的是,这会产生以下错误: IllegalArgumentException不知道如何从以下位置创建ISeq:用户$eval10144$fibgen\uuu 10145 clojure.lang.RT.seqFrom(RT.java:528) 这怎么能解决呢?我想你刚才打错了。以下是

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

(take 10 (fn fibgen [a b] (cons a (fibgen b (+ a b))) 0 1))
其思想是,
fibgen
创建一个惰性序列(无限流)。不幸的是,这会产生以下错误:

IllegalArgumentException不知道如何从以下位置创建ISeq:
用户$eval10144$fibgen\uuu 10145 clojure.lang.RT.seqFrom(RT.java:528)


这怎么能解决呢?

我想你刚才打错了。以下是重新格式化后的
fibgen
函数的外观:

(fn fibgen [a b]
  (cons a (fibgen b (+ a b)))
  0
  1)
此函数实现从
a
b
开始的整个斐波那契序列,然后返回1。您要做的是定义一个返回序列的函数,用0和1调用它,然后从该序列中提取前十项:

(take 10 ((fn fibgen [a b] (cons a (fibgen b (+ a b)))) 0 1))
如果运行此命令,您将得到整数溢出的
算术异常
,因为斐波那契序列中的数字很快就会离开64位整数的范围。您可以使用以下方法修复此问题:

由于Clojure并不懒惰,因此将尝试实现整个斐波那契序列,这将导致出现
堆栈溢出错误。尽管Clojure本身并不懒惰,但您可以创建一个,在本例中基本上具有相同的效果:

(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)

你从不调用函数,如果你真的调用它,它也不会被调用lazy@noisesmith我现在确实明白了。:)非常感谢。还有一个问题我希望你能回答:如果Clojure不是懒惰的,为什么
map
创建一个懒惰的seq?Clojure是一种严格的语言,这意味着默认情况下,值以实现的形式存储,而不是存储为仅在需要时才实现的thunk。然而,这并不意味着你不能使用thunks;该函数使用宏,该宏将一段代码封装到空函数中,并返回一个对象,该对象仅在要求调用该函数(并缓存其结果)时才会调用该函数。
(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)