例如,以这样的形式:
let f = [ a | a <- [1..], a == a - 1]
我只是好奇。看起来它是可能的,但我无法完全理解它是如何工作的。这个问题更多的是为了理解Haskell的工作原理,而不是因为我正在寻找一个实际的应用程序。
此外,我知道有类似的问题已被提出,但我所看到的帖子都没有提供任何帮助,而是我很好奇。
编辑:抱歉模糊不清。那么让我澄清一条新规则。挑战是找到一种方法来代表一个无限的斐波纳契数列表,使用从了解你的好东西的第一章中的额外内容!尽可能。怎么样?换句话说,你能想到的最具创造性的方式就是用尽可能少的知识生成这些数字&#39;尽可能。抱歉让任何人回答无效,现在。
答案 0 :(得分:8)
试试这个:
import Data.List (tails)
fib :: [Integer]
fib = 0 : 1 : [ a + b | (a:b:_) <- tails fib ]
是的,它使用cons运算符(:)
作为种子值。不过我相信可以赦免。
答案 1 :(得分:3)
肯定有一个令人讨厌的伎俩:有a closed form of the Fibonacci sequence
f n =(φ n - ψ n )/√5
所以
Prelude> let (φ, ψ) = (1/2+s, 1/2-s) where s = sqrt(5/4)
Prelude> let fibs = [ round $ (φ^n - ψ^n) / sqrt 5 | n <- [0..] ]
Prelude> take 20 fibs
[0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181]
这在浮点运行,因此它非常快,但无法在高值下正常工作:
Prelude> take 3 $ drop 80 fibs
[23416728348467676,37889062373143896,61305790721611584]
Prelude> 23416728348467676 + 37889062373143896 - 61305790721611584
-12
我认为如果不利用不合理的数字或在理解中加入一些递归就行不通,因为列表推导只是monadic绑定的语法糖而且它们本身并不是图灵完备的,所以它们不能产生无限的建设性的顺序。
答案 2 :(得分:2)
最简单的当然是:
fibs = f 0 1 where f a b = a : (f b (a+b))
我们从定义中得出这个解决方案。
让f a b
计算以a
开头并后跟b
的数字流。然后我们可以使用f
来计算b
之后的数字子流,如果我们可以在b
之后立即计算数字。我们知道在b
跟随a+b
之后,我们立即获取该流并将其附加到a
。
答案 3 :(得分:0)
此解决方案不涉及任何列表库函数,而是使用列表推导。
fib = [ x | (x,_) <- l ]
where l = (0,1) : [ (b,a+b) | (a,b) <- l ]