【问题标题】:Fibonacci infinite list in HaskellHaskell中的斐波那契无限列表
【发布时间】:2018-04-30 13:17:55
【问题描述】:

我想创建一个斐波那契数列。 我想调用 fib x 它应该给我一个列表,直到第 x 个元素。 我如何做到这一点。

我会这样计算 fib 数:

fib 0 = 0
fib 1 = 1
fib n = fib (n-1) + fib (n-2)

如何将结果放入列表中以调用列表直到我需要的元素?

【问题讨论】:

  • 以上不是一个高效的实现,它会在指数时间内运行。
  • 喜欢this

标签: list haskell list-comprehension fibonacci


【解决方案1】:

一个紧凑的定义(线性缩放)如下:

fib :: Num n => [n]
fib = 0 : nxt
    where nxt = 1 : zipWith (+) fib nxt

fibN :: Num n => Int -> [n]
fibN = flip take fib

我们在这里所做的是构建一个列表fib,它是0nxt(其余列表)的“缺点”。 nxtwhere 子句中定义为 1 的“缺点”和 zipWith (+) fib nxt 的结果。 zipWith elementwise 将fibnxt 的元素加在一起,因为nxt 总是fib 的“前面”一个元素,因此我们将最后两个元素加在一起。然后我们 taken 函数中的第一个 n 元素。

所以我们得到一个类似的列表:

   fib          nxt
    |            |
    v            v
+-------+    +-------+    +-------------+
|  (:)  | ,->|  (:)  | ,->|   zipWith   |
+---+---+ |  +---+---+ |  +-----+---+---+
| 0 | o---'  | 1 | o---'  | (+) | o | o |
+---+---+    +---+---+    +-----+-|-+-|-+
  ^            ^                  |   |
  |            `------------------|---'
  `-------------------------------'

如果我们因此评估到第三个元素,这意味着我们调用zipWith,这将产生fibnxt 的头部之和并推进两个点,例如:

   fib          nxt
    |            |
    v            v
+-------+    +-------+    +-------+    +-------------+
|  (:)  | ,->|  (:)  | ,->|  (:)  | ,->|   zipWith   |
+---+---+ |  +---+---+ |  +---+---+ |  +-----+---+---+
| 0 | o---'  | 1 | o---'  | 1 | o---'  | (+) | o | o |
+---+---+    +---+---+    +---+---+    +-----+-|-+-|-+
               ^            ^                  |   |
               |            `------------------|---'
               `-------------------------------'

等等。

【讨论】:

  • 谢谢你的例子。图形也是一个很好的帮助。我问自己你是怎么做那个图形的? :D 你有什么程序可以帮助你创建这种图形还是你自己做的?
  • @CoreNoob:我自己写了 ascii 艺术 :)
【解决方案2】:

不是一个快速的方法(因为你的函数在指数时间内运行),但使用你的函数fib

nfibs :: Int -> [Integer]
nfibs n = take n (map fib [0..])

【讨论】:

  • 你可以去掉签名的Int ->部分:)
  • 不,我只是忘记将它包含在 LHS 中(他想要最多第 n 个元素)
  • take + 无限列表非常模块化,但是当它是本地的时,我会亲自重写为map fib [0..n-1]
  • 你是对的,但我认为这作为教学示例更有用。也许将map fib [0..] 移到where 子句会更清楚?
猜你喜欢
  • 2014-05-19
  • 2011-02-17
  • 2017-12-06
  • 2018-07-03
  • 1970-01-01
  • 2015-01-06
  • 1970-01-01
  • 2015-06-28
相关资源
最近更新 更多