Basic summation in Haskell
I'm practicing Haskell, and writing a summation function that takes in two numbers (upper and lower limits) and does the summation.
ie, summation 0 10
would return 55
I can get it mostly working, but having trouble figuring out how to get it using only two parameters.
Here is what I have so far:
summation :: Integer -> Integer -> Integer -> Integer
summation x y sum =
if (y<x) then
sum
else
summation x (y-1) (sum+y)
So this works fine, but I need to do summation 0 10 0
to get it working properly. I'm not sure how I can get this working with only two parameters in Haskell.开发者_如何转开发
You wrap it.
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)
The quick answer:
One simple way would be to use the sum
function from Data.List
.
Then you could simply say:
summation x y = sum [x .. y]
This solution assumes that x
is less than y
, and you could fix this by saying:
summation x y = sum [min x y .. max x y]
Defining sum
:
Since you are learning Haskell, it might be important to know how sum
works, instead of just knowing it exists. For me, the biggest hurdle to get over initially was writing too many functions that already existed; especially since I didn't know how to write them effectively.
Hoogle is a great help in this regard: it's a search engine that allows you to seach for Haskell functions. It's a great thing for productivity, because you'll be able to spend time working on your problem, instead of producing poor rewrites of half of the prelude. It's also great for learning, because there are links to the source code of most of the functions on Hackage. The source code of the Prelude
and other "fundamental" libraries such as Data.List
is surprisingly accessible to a beginner, and will provide a lot of insight into how "the smart kids" do things.
The :browse
command in GHCI is something that I found out about recently that I wish I'd discovered sooner.
Anyway, one way of defining sum
is by using a fold:
sum xs y = foldl (+) 0 xs
Or the equivalent in "pointless" style:
sum = foldl (+) 0
I usually prefer the first formulation, but knowing how and why the second one works will help you a lot in your journey.
Further Reading:
You'll notice that I used the function foldl
. This function "folds" an input list. To "master" functional programming, knowing how to fold
is both one of the most basic and important concepts. A good resource to consult is the page on folds from the Haskell Wiki.
You could do it like Gauss did.
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
Code is a blatantly literal translation from http://mathcentral.uregina.ca/QQ/database/QQ.02.06/jo1.html (a little ways down that page: S = n[2a + (n-1)d]/2
)
精彩评论