评估Haskell中的递归函数

时间:2016-12-31 12:34:33

标签: haskell

我获得此功能并要求手动评估g 5。我发现答案是25,但这是不正确的。正确答案是63.有人能帮助我理解为什么吗?感谢

g :: Int -> Int
g n 
  | n==0      = 1
  | otherwise = 2 * g (n-1) + 1

我的回答:(2 * 4 + 1)+(2 * 3 + 1)+(2 * 2 + 1)+(2 * 1 + 1)+ 1 = 25

4 个答案:

答案 0 :(得分:8)

你只需要一步一步地思考:

(g 5) = 2 * (g 4) + 1
(g 4) = 2 * (g 3) + 1
(g 3) = 2 * (g 2) + 1
(g 2) = 2 * (g 1) + 1
(g 1) = 2 * (g 0) + 1
(g 0) = 1

然后,插入自下而上的值:

2 * 1 + 1 = 3
2 * 3 + 1 = 7
2 * 7 + 1 = 15
2 * 15 + 1 = 31
2 * 31 + 1 = 63

您的问题是您使用的是n的原始值,而不是在递归结束时返回的(g n)

答案 1 :(得分:2)

在你的计算中,你搞砸了术语的嵌套。它们应该嵌套,而不是单独总结。

评估此类函数的方法是将函数体替换为函数体,并将其参数替换为给定参数。我将完成前几个步骤然后你可以接管:

g 5
if 5 == 0 then 1 else 2 * g (5-1) + 1
2 * g (5-1) + 1
2 * (if (5 - 1) == 0 then 1 else 2 * g ((5-1) - 1) + 1) + 1
2 * (if 4 == 0 then 1 else 2 * g (4-1) + 1) + 1
2 * (2 * g (4-1) + 1) + 1
...
63

@ Carcigenicate的答案当然更容易计算,但这种技术更具普遍性,更符合代码的实际运作方式。

答案 2 :(得分:0)

虽然这不是你的问题,但通过归纳显示很容易

g n = 2^(n+1)-1

所以

g 5 = 2^6 - 1 --> 63

答案 3 :(得分:0)

你的括号是错误的。没有做任何减少(除了扩展g),我们得到

g 5
= 2 * g 4 + 1
= 2 * (2 * g 3 + 1) + 1
= 2 * (2 * (2 * g 2 + 1) + 1) + 1
= 2 * (2 * (2 * (2 * g 1 + 1) + 1) + 1) + 1
= 2 * (2 * (2 * (2 * (2 * g 0 + 1) + 1) + 1) + 1) + 1
= 2 * (2 * (2 * (2 * (2 * 1 + 1) + 1) + 1) + 1) + 1