I\'m trying to carry out the following computation: sum of the squares of integers in the range x:y where (x <= y).
I\'m not sure how to put a constraint to ensur
In GHCI do these steps to see what's going on:
Prelude> let sq x = x^2
Prelude> let list = [1..5]
Prelude> list
[1,2,3,4,5]
Prelude> let listOfSq = map sq list
Prelude> listOfSq
[1,4,9,16,25]
Prelude> sum listOfSq
55
The shorthand would be exactly what Jubobs suggested:
sum $ map (^2) [1..5]
EDIT: To error out when Y is greater than X you can do something like this
sumOfSquares :: Integer -> Integer -> Integer
sumOfSquares x y | y <= x = error "Y must be greater than X"
| otherwise = sum $ map (^2) [x..y]
The obvious and slow approach is to actually sum those squares:
sumOfSquaresSlow :: Integral a => a -> a -> a
sumOfSquaresSlow lo hi
| lo > hi = error "sumOfSquaresSlow: lo > hi"
| otherwise = sum $ map (^2) [lo..hi]
The time complexity of this approach is linear in max(y-x,0); it will take a while if your range of integers is large; see the benchmark at the bottom of my answer.
However, because there is a formula for the sum of the squares of the first n (positive) integers, you don't actually have to sum those squares one by one.
To issue an error message to the user in case x
is greater that y
(as specified in your comment), you can simply use the error
function, here.
(Edit: thanks to Chris Drost for pointing out that I was overcomplicating things)
sumOfSquaresFast :: Integral a => a -> a -> a
sumOfSquaresFast lo hi
| lo > hi = error "sumOfSquaresFast: lo > hi"
| otherwise = ssq hi - ssq (lo - 1)
where
ssq x = div (((2 * x + 3) * x + 1) * x) 6
Using this formula instead reduces the complexity to something close to constant time.
λ> :set +s
λ> sumOfSquaresSlow (10^3) (10^7)
333333383333002166500
(17.19 secs, 11563005552 bytes)
λ> sumOfSquaresFast (10^3) (10^7)
333333383333002166500
(0.01 secs, 3106112 bytes)
Using list comprehension:
squareSum from to
| from > to = error "wrong input"
| otherwise = sum [i^2 | i <- [from..to]]
UPDATE: updated after OP has updated the question