I'm working on an assignment to calculate the sum of all integers in a list. I am supposed to do so without help from any standard library functions other than the standard addition operator.
I assume this means I cannot use length
. I'm understanding that correct, right? This becomes and issue as I'm not sure how I'd know when to stop my recursive function to iterate through the array.
The input's a should be expected to deal with are []
and [0-X]
where x is any integer. The example has X as 10, so don't expect anything huge to be tested.
The assignment mentioned it should be in the following format, but I'm not sure I follow:
sum1 [] = ...
sum1 (x:xs) = ...
Here's what I have utilizing length. It works correctly, and I don't really care if it's inefficient. It's my first time using Haskell:
iterate_list :: [Int] -> Int -> Int -> IO()
iterate_list func_list index total = do
if index < length func_list
then do
let new_total = total + (func_list !! index)
let new_index = index + 1
iterate_list func_list new_index new_total
else
print(total)
sum1 :: [Int] -> IO()
sum1 list = do
if length list < 1
then do
print(0)
else
iterate_list list 0 0
update: Based on comments, here is the code I've produced.
total :: Int
total = 0
sum1 :: [Int] -> IO()
sum1 (x:xs) = do
if xs == []
then do
print(total)
else do
let total = total + x
sum1 xs
However, the issue I'm having now is total
returns 0, almost like it's a constant. I might be programming it that way, but I'm not too sure what's going on.
Based on the assignment description, I cannot pass a variable through the recursive function to store this value. I've done it that way before. Does anyone know if there is a way to have a "total
" variable outside of the function.
total :: Int
total = 0
sum1 :: [Int] -> IO()
sum1 (x:xs) = do
if xs == []
then do
print(total)
else do
let total = total + x
sum1 xs
What this code says:
The global total
is a constant integer, equal to 0
sum1
takes a list of integers and produces an IO action that produces no result
If sum1
is given a non-empty list, then:
If the tail of that list is empty (i.e., the whole list has 1 element), then print the global variable total
Otherwise:
Create a new local variable named total
, hiding the global one, and define it as x
plus itself (an infinite loop)
Recursively call sum1
on the tail of the list
If sum1
is given an empty list, it will throw an error
This shows that you’re thinking very imperatively. Rather than trying to define a bottom-up procedure for updating the total incrementally until it builds up to the final result, you need to think in terms of how to compute the total as a value by breaking down the input. Variables in Haskell are immutable; when you write =
, it means equal, never “assign” or “update”.
First, sum1
should return Int
because you don’t need IO
or do
notation for this.
sum1 :: [Int] -> Int
If you want to print the result of sum1
applied to some list someList
(for example from main
), use print
there, i.e., print (sum1 someList)
.
Next, the function should be defined in terms of the the two possible cases of the input: an empty list and a non-empty list.
sum1 [] = …
sum1 (x : xs) = …
You need to define these cases so that an input like sum1 [1, 2, 3, 4]
, which you’ll recall is syntactic sugar for sum1 (1 : (2 : (3 : (4 : []))))
produces something equivalent to 1 + 2 + 3 + 4
.
First, in the case of an empty list, what should the result be? You can deduce this from the fact that the sum of two lists appended together should be the same as the sum of each of them separately; that is, for any lists xs
and ys
, these expressions should produce the same result:
sum1 xs + sum1 ys
sum1 (xs ++ ys)
Supposing xs
or ys
is empty, it should not change the sum:
sum1 [] + sum1 ys
= sum1 ([] ++ ys)
= sum1 ys
sum1 xs + sum1 []
= sum1 (xs ++ [])
= sum1 xs
Second, as for the non-empty case: you’re given an element x :: Int
and a list xs :: [Int]
, and you need to compute the total of the two. For example, given [1, 2, 3, 4]
, x
is set to 1
and xs
is [2, 3, 4]
. Suppose you had the sum of xs
already; what is the result in terms of that and x
? And how can you obtain the sum of xs
?