在Haskell中用列表解析定义无穷Fibonacci数列

6jygbczu  于 2022-11-14  发布在  其他
关注(0)|答案(3)|浏览(171)

我该怎么做呢?这是我课堂幻灯片中练习的一部分,提示是使用库函数tail :: [a] -> [a]zip :: [a] -> [b] -> [(a,b)]。另外,函数的类型是fibs :: [Integer]
我知道列表解析的工作原理,知道如何编写一个递归的斐波那契函数,并且熟悉tail和zip函数--但是,我就是搞不懂这个,也没能在网上找到一个例子。有人能告诉我它是怎么做的吗?
同样出于好奇,像这样的函数(产生一个无限列表)是如何在Haskell中使用的呢?例如,如果我在ghci命令提示符中写入fibs(函数名),它会继续打印列表中的元素直到时间结束吗?
提前感谢您的帮助。

oewdyzsn

oewdyzsn1#

给你个提示。
取2的幂序列。

p2 = [1, 2, 4, 8, 16 ...

zip它本身

zip p2 p2 = [(1,1), (2,2), (4,4), ...]

对列表中的每一对求和(这可以使用列表解析来完成)

[2, 4, 8, ...

前置1

[1, 2, 4, 8, ...

所以我们又得到了p2列表。如果你用Haskell来表达所有这些,你最终得到的代码形式为

p2 = 1 : ... something involving p2 ...

这是一个产生2的幂的工作程序。
一旦你得到这个工作,你可以改变它 * 轻微 *,并获得斐波纳奇以及。
对于最后一点:是的,打印p2将打印整个无限序列。

take 10 p2
waxmsbnn

waxmsbnn2#

下面是另一个chi风格(希望您不要介意):
写下谎言:

fibs = 1 1 2 3 5 8 13 ...

再写一遍,但左移一位:

fibs       = 1 1 2 3 5 8 13 ...
(??? fibs) = 1 2 3 5 8 13 ...

添加它们:

fibs       = 1 1 2 3 5 8 13 ...
(??? fibs) = 1 2 3 5 8 13 ...
--------------------
(+ em)     = 2 3 5 8 13 21 ...

看起来眼熟吗
现在你只需要(再次)在前面加上一些东西,并思考一下这里的 shift left 是什么意思(hint 你提到过):

fibs       = 1 1 2 3 5 8 13 ...
(??? fibs) = 1 2 3 5 8 13 ...
--------------------
(+ em)     = 2 3 5 8 13 21 ...
=> fibs = ? : ((+ em) fibs (??? fibs))

同样,使用zipWith (+)也可以很好地进行求和
玩得开心点

xienkqul

xienkqul3#

下面是我使用zip和tail找到的解决方案:

fibs :: [Integer]
fibs = 0:1:[x + y | (x,y) <- zip fibs (tail fibs)]

如果你运行fib,它会一直打印,直到计算机内存耗尽并崩溃。你可以通过taketakeWhile调用返回无限列表的函数来返回有限列表。Haskell使用惰性求值来使处理无限数据结构更高效。
示例:
take 10 fibs
印刷品:
[0,1,1,2,3,5,8,13,21,34]

相关问题