迭代函数不保存中间步骤?

发布于 2024-11-05 06:41:12 字数 452 浏览 0 评论 0原文

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

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

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

(我见过更好/更短/更漂亮的生成斐波那契序列的方法,所以我并不是真的在寻找关于 fib 函数的反馈 - 但我想让它工作,次优方法或不)

I just started learning Haskell, and as an exercise got into a Project Euler problem where Fibonacci numbers are summed. My current method is this function, which creates a new list with the next element:

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

I found the function iterate which reapplies the function on it's result. However, the result is a list of lists, [[2,1],[3,2,1],[5,3,2,1],..]. What is the alternative to iterate when I'm not interested in the intermediate results? I want to do a takeWhile with a condition on the last generated number. Is this the wrong way to think about it altogether?

(I've seen better/shorter/niftier ways of generating the Fibonacci sequence, so I'm not really looking for feedback on the fib function - but I'd like to make it work, suboptimal method or not)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

晒暮凉 2024-11-12 06:41:12

只需使用迭代!因为 Haskell 是一种纯语言,所以所有子列表都会共享,并且您基本上无需为生成所有这些迷你列表付出任何成本: [2, 1] 实际上是 2, 1< /code> 在 [3, 2, 1] 中,依此类推。

您实际上并不需要 takeWhile,因为这会给您带来很多额外的麻烦,并且您仍然需要使用 last 到达列表的末尾。相反,请使用find

另请注意,如果您打算对结果列表进行求和,那么您就错过了 1,因此您可能会失败。

Just use iterate! Because Haskell is a pure language, all of the sublists get shared and you pay essentially no cost for having generated all of those mini lists: [2, 1] is actually the 2, 1 in [3, 2, 1], and so forth.

You don't really want a takeWhile, because that will give you a lot of extra gunk and you'll still need to get to the end of the list with last. Instead, use find.

Also note that if you're planning on summing the resulting list, you've missed a 1 so you'll be one off.

难得心□动 2024-11-12 06:41:12

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

这是同一个家庭作业吗?

I'm not sure about the use of iterate, but see Filtering fibonacci sequence in Haskell for how to filter a list of fibs.

Is this the same homework assignment?

情何以堪。 2024-11-12 06:41:12

我会使用“take”,因为每个连续的近似值都会比上一个更准确。然后你可以对其进行 (head .reverse) 操作。

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

I would use "take", since each successive approximation will be one integer more accurate than the last. You can then do (head . reverse) on that.

Note that "every" result is an intermediate result if the function you are iterating doesn't have a computable fixed point.

无尽的现实 2024-11-12 06:41:12

当在 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]

我很确定那里有是使用折叠(或我忘记的库函数:))来做到这一点的更简洁的方法

When needing a function in Haskell just define it :)

The folowing isn't the most elegant or idiomatic Haskell, but serves to show that you can always do things by hand with a tail recursive loop if the need arises

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]

I'm pretty sure there is a neater way to do this using folds (or a library function I forgot about :) )

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文