我正在练习Haskell,并编写一个求和函数,它接受两个数字(上限和下限)并进行求和。
即,summation 0 10
将返回55
我可以让它主要工作,但是很难找到如何仅使用两个参数来获取它。
这是我到目前为止所做的:
summation :: Integer -> Integer -> Integer -> Integer
summation x y sum =
if (y<x) then
sum
else
summation x (y-1) (sum+y)
所以这很好用,但我需要做summation 0 10 0
才能让它正常工作。我不知道如何才能在Haskell中只使用两个参数。
答案 0 :(得分:10)
你把它包起来。
summation :: Integer -> Integer -> Integer
summation x y = summation' x y 0
summation' :: Integer -> Integer -> Integer -> Integer
summation' x y sum =
if (y<x) then
sum
else
summation' x (y-1) (sum+y)
答案 1 :(得分:10)
一种简单的方法是使用sum
中的Data.List
函数。
然后你可以简单地说:
summation x y = sum [x .. y]
此解决方案假设x
小于y
,您可以通过以下方式解决此问题:
summation x y = sum [min x y .. max x y]
sum
:由于您正在学习Haskell,因此了解sum
如何工作可能很重要,而不仅仅是知道它存在。对我来说,最初克服的最大障碍是编写已经存在的太多功能;特别是因为我不知道如何有效地写它们。
Hoogle在这方面是一个很好的帮助:它是一个搜索引擎,允许你搜索Haskell函数。这对于提高工作效率来说是一件好事,因为你可以花时间处理你的问题,而不是对前奏的一半做出糟糕的重写。它也非常适合学习,因为Hackage上有大多数功能的源代码链接。 Prelude
和其他“基本”库(如Data.List
)的源代码对初学者来说非常容易获取,并且会为“聪明的孩子”如何做事提供大量见解。
GHCI中的:browse
命令是我最近发现的,我希望我能早点发现。
无论如何,定义sum
的一种方法是使用折叠:
sum xs y = foldl (+) 0 xs
或"pointless" style中的等价物:
sum = foldl (+) 0
我通常更喜欢第一种配方,但知道第二种配方的工作方式和原因会对您的旅程有所帮助。
你会注意到我使用了函数foldl
。此功能“折叠”输入列表。要“掌握”函数式编程,了解如何fold
是最基本和最重要的概念之一。一个很好的咨询资源是来自page on folds的Haskell Wiki。
答案 2 :(得分:4)
你可以像高斯那样做。
summation begin end
| end < begin = summation end begin
| otherwise = n * (2*a + (n-1)*d) `div` 2
where a = begin
d = 1
n = end - begin + 1
代码是来自http://mathcentral.uregina.ca/QQ/database/QQ.02.06/jo1.html的明显字面翻译(在该页面的一点点:S = n[2a + (n-1)d]/2
)