4

我刚开始学习 Haskell,并作为练习进入了一个欧拉计划问题,其中斐波那契数相加。我当前的方法是这个函数,它创建一个包含下一个元素的新列表:

fib :: (Integral a) => [a] -> [a]
fib xs@(x1:x2:_) = (x1+x2) : xs

我找到了iterate在结果上重新应用函数的函数。但是,结果是一个列表列表,[[2,1],[3,2,1],[5,3,2,1],..]. iterate当我对中间结果不感兴趣时​​,有什么替代方法?我想对takeWhile最后生成的数字做一个条件。这是完全错误的思考方式吗?

(我已经看到了生成斐波那契数列的更好/更短/更好的方法,所以我并不是真的在寻找有关该fib函数的反馈 - 但我想让它工作,无论是否是次优方法)

4

4 回答 4

3

只需使用iterate!因为 Haskell 是一种纯语言,所有的子列表都可以共享,并且您基本上不需要为生成所有这些迷你列表支付任何费用:[2, 1]实际上是2, 1in [3, 2, 1],等等。

您并不真正想要takeWhile,因为这会给您带来很多额外的垃圾,您仍然需要使用 . 到达列表的末尾last。相反,使用find.

另请注意,如果您打算对结果列表求和,那么您错过了 a 1,因此您将被淘汰。

于 2011-05-04T20:58:18.967 回答
0

我会使用“take”,因为每个逐次逼近都会比上一个更准确一个整数。然后你可以做 (head . reverse) 。

请注意,如果您正在迭代的函数没有可计算的不动点,则“每个”结果都是中间结果。

于 2011-05-04T20:33:52.227 回答
0

我不确定如何使用iterate,但请参阅在 Haskell 中过滤斐波那契序列以了解如何过滤 fib 列表。

这是同一个家庭作业吗?

于 2011-05-04T20:11:33.737 回答
0

当在 Haskell 中需要一个函数时,只需定义它:)

以下不是最优雅或最惯用的 Haskell,但它表明如果需要,您始终可以使用尾递归循环手动完成任务

apply_n f n x =
    if n = 0 then x
    else apply_n' f (n-1) (f x)

n_th_fib n = apply_n fib n [1,1]

我很确定有一种更简洁的方法可以使用折叠(或我忘记的库函数:))

于 2011-05-04T21:13:39.587 回答