首先,您需要描述您的功能。
sumFirstOdds :: Int -> Int
当您考虑递归时,您将需要一个停止点。在这种情况下,一个好的停止点是前零个奇数的总和,也就是零。您可以像这样定义基本情况:
sumFirstOdds 0 = 0
在编写递归函数时,最好养成先声明停止点的习惯。否则你很容易陷入无限循环。
现在我们需要定义当我们想要找到n > 0 时第一个n 奇数之和时会发生什么。
您首先需要找到一种方法来获取第 n 个奇数的值:(n * 2) - 1。
现在是递归部分。它可以帮助您通过几个简单的示例来思考问题。如果我们想得到前 3 个奇数的总和,我们会使用这样的公式:
((3 * 2) - 1) + ((2 * 2) - 1) + ((1 * 2) - 1) + 0
^ ^ ^ ^
| | | |
n == 3 n == 2 n == 1 n == 0 (base case)
从请求的数字 3 开始使用相同的算法,并将其添加到对 2 运行相同算法的结果中,然后对 1 执行相同的操作,然后对 0 执行相同的操作,这就是我们达到基本情况的地方然后停下来。
放入 Haskell 代码,你可以这样写:
sumFirstOdds n = ((n * 2) - 1) + (sumFirstOdds (n-1))
针对当前的n 值执行计算,并将该值添加到针对该n-1 值使用的相同函数的结果中。
重申一下最终函数的样子,如下:
sumFirstOdds :: Int -> Int
sumFirstOdds 0 = 0
sumFirstOdds n = ((n * 2) - 1) + (sumFirstOdds (n-1))
注意:这不能很好地处理负输入,但为了简单起见,我把它省略了