有人能告诉我以下功能是如何运作的吗?
特别是fibu'
- 东西和元组?谢谢!
fibu :: Integer -> Integer
fibu x = fst (fibu' x)
where fibu' 0 = (0, 0)
fibu' 1 = (1, 0)
fibu' n = (a + l, l)
where (l, a) = fibu' (n-1)
答案 0 :(得分:4)
您可能已经看到了Fibonacci序列的天真实现:
fibo :: Integer -> Integer
fibo 0 = 0
fibo 1 = 1
fibo n = fibo (n-1) + fibo (n-2)
嗯,问题是该函数递归地调用自己两次。而且这些呼叫中的每一个都会再次召唤两次......所以最终会有大量的呼叫。
你要问的实现是什么来解决这个问题:它不仅返回 n -th Fibonacci数,还返回 n -th和< EM>名词的-1次。然后 n + 1-call只需要一个额外调用,而不是两个,因为一次调用为计算序列的下一个元素提供了所需的全部。
对于最终结果,您不需要两个数字但只需要一个,因此倒数第二个值将使用fst
丢弃。
答案 1 :(得分:3)
让我们先分析一下
fibu' 0 = (0, 0)
fibu' 1 = (1, 0)
fibu' n = (a + l, l)
where (l, a) = fibu' (n-1)
这里我们有一个函数,它将一个数字 i 作为输入,并返回一个带有两个数字的2元组。这两个数字是(F i ,F i-1 ) F i i -th斐波纳契数。
前两个数字( i = 0 , i = 1 )是硬编码的((0, 0)
和(1, 0)
)。但当然我们不能保持对Fibonacci值的硬编码。如果我不是0
或1
,则会触发最后一行。实现此案例是为了处理i-1
案例。
在这种情况下,我们递归计算fibu' (n-1)
(所以包含的元组(F n-1 ,F n-2 ),我们在之前的两个Fibonacci数中计算出来。然后我们知道(这是Fibonacci归纳关系 F n = F n-1 + F n-2 )。这意味着我们可以返回(a+l, l)
。所以如果我们调用fibu' 5
实例,它会调用fibu' 4
, fibu' 3
等等,直到我们到达fibu' 1
然后我们每次都会构造一个新的元组来继续计算最后两个斐波纳契数,直到我们达到索引为5
的斐波纳契数
现在fibu'
唯一的问题是它返回一个2元组,用户通常想得到一个简单的数字( i -th Fibonacci数)。所以现在我们定义一个函数:
fibu :: Integer -Integer
fibu x = fst (fibu' x)
这将返回2元组的第一个项目( i -th Fibonacci编号)。