【问题标题】:Problem with Fibonacci Haskell Implementation斐波那契 Haskell 实现的问题
【发布时间】:2011-09-27 14:09:42
【问题描述】:

刚开始重新学习 Haskell(在大学学过,但大部分都忘记了),并认为我会实现一个 Fibonacci 函数作为开始。但是,我不断收到 stackoverflow,即使对于非常小的 n

谁能发现我的功能有任何问题?

fib :: Integer -> Integer
fib 0 = 0
fib 1 = 1
fib n = fib (n-1) + fib (n+1)

【问题讨论】:

  • 提示 - 您可能想查看这本免费书籍:book.realworldhaskell.org
  • 请注意,斐波那契数在 Haskell 中通常写为 fibs = 0 : 1 : zipWith (+) fibs (tail fibs)

标签: haskell stack-overflow fibonacci


【解决方案1】:

这是一个非常糟糕的实现,你应该使用尾递归,从 0 或 1 开始向上并传递前两个斐波那契数。还有一个bug,fib n 依赖于fib n+1。

fib :: Integer -> Integer
fib 0 = 0
fib n = iter 0 1 n
  where iter :: Integer -> Integer -> Integer -> Integer
        iter f1 f2 0 = f2
        iter f1 f2 n = iter f2 (f1+f2) (n-1)

【讨论】:

  • 作为一个学习练习,我认为这样做没有问题。虽然我同意这不是最优化的实现
  • 嗯,我不太确定,尾递归是所有函数式编程语言的基础。该代码是指数的,尝试一个非常简单的fib 50。好吧,“非常糟糕”可能有点粗鲁,抱歉 :)
  • 我同意,但让 OP 至少先得到简单的递归和模式匹配排序
  • 其实你需要严格注解,否则尾递归将不起作用(或者优化器可能会为你添加)
  • @yi_H 虽然尾递归很重要,但它在 Haskell 中不如在严格的函数式语言中重要。例如,map 不是尾递归的,但它的工作原理与长列表一样。事实上,它可以正常工作,因为它不是尾递归的。
【解决方案2】:

您的斐波那契公式有误:

fib :: Integer -> Integer
fib 0 = 0
fib 1 = 1
fib n = fib (n-1) + fib (n-2)

请注意最后一个术语是 n-2 而不是 n+1

【讨论】:

    猜你喜欢
    • 2011-12-12
    • 2017-12-06
    • 2015-01-06
    • 2010-11-24
    • 1970-01-01
    • 2012-07-24
    • 2018-07-03
    • 2013-04-15
    • 2011-02-17
    相关资源
    最近更新 更多