我是Haskell的新手 - 以及函数式编程 - 我想知道如何在Haskell中编写这样的函数。我已经习惯了命令式语言,但是现在处理haskell中的递归对我来说是难以捉摸的。注意,我知道奇数的和可以用n ^ 2来完成(即3个第一奇数的总和1 + 3 + 5 = 9 = 3 ^ 2)但是想法是学习函数编程的递归。
另外,我这样做是代数研讨会的一部分,我们还没有看到。我需要一种方法来解决它只有递归。
任何提示?谢谢!
答案 0 :(得分:9)
-- the odd numbers (all of them!)
[ 1,3.. ]
-- the first N odd numbers:
take n [1,3..]
-- the sum of the first N odd numbers
sum (take n [1,3..])
把它放在一个函数中:
sumOddNumbers n = sum (take n [1,3..])
答案 1 :(得分:5)
首先,您需要描述您的功能。
sumFirstOdds :: Int -> Int
当你考虑递归时,你需要一个停止点。在这种情况下,良好的停止点是第一个零奇数的总和,即零。您可以像这样定义基本情况:
sumFirstOdds 0 = 0
养成在你编写递归函数时首先声明停止点的习惯是很好的。否则你很容易就会遇到无限循环。
现在我们需要定义当我们想要在n
时找到第一个n > 0
奇数的总和时会发生什么。
您首先需要找到一种方法来获取第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))
注意:这并不能很好地处理负输入但我为了简单起见而将其排除在外
答案 2 :(得分:2)
因为你应该总是通过平方来对奇数求和,我认为用递归来那个会很有趣。既然对var Dog = function(name){
this.name = name;
}
Dog.prototype.type = function(){
return this;
}
Dog.prototype.getName = function(){
//console.log(this.type())
return "Dog's name: " + this.type(); // <- Calls toString method
}
Dog.prototype.toString = function(){
return this.name;
};
var spot = new Dog('spot');
console.log(spot.getName());
或Int
采用这种方式很愚蠢,那么您应该在类型级别工作。这实际上和总结天真的方式一样慢,但它更有趣!
Integer
现在,为了使这个可用,你可以用单身人士将它降低到术语水平。
{-# LANGUAGE DataKinds, KindSignatures, TypeFamilies, TypeOperators, GADTs, UndecidableInstances #-}
data Nat = Z | S Nat
infixr 6 :+
type family (:+) (x :: Nat) (y :: Nat) :: Nat where
'Z :+ n = n
'S m :+ n = 'S (m :+ n)
infixr 7 :*
type family (:*) (x :: Nat) (y :: Nat) :: Nat where
'Z :* n = 'Z
'S m :* n = n :+ m :* n
答案 3 :(得分:1)
这里不需要,但通常可以在辅助函数中使用累加器进行递归计算。
sumodds n = go n 0
where go 0 a = a
go k a = go (k-1) (a + 2*k-1)
> map sumodds [0..9]
[0,1,4,9,16,25,36,49,64,81]