im searching for a solution for my Haskell class.
I have a list of numbers and i need to return SUM for every part of list. Parts are divided by 0. I need to use FOLDL function.
Example:
initial list: [1,2,3,0,3,4,0,5,2,1]
sublist [[1,2,3],[3,4],[5,2,1]]
result [6,7,7]
I have a function for finding 0 in initial list:
findPos list = [index+1 | (index, e) <- zip [0..] list, e == 0]
(returns [4,6] for initial list from example)
and function for making SUM with FOLDL:
sumList list = foldl (+) 0 list
But I completely failed to put it together :/
—- MY SOLUTION
In the end I found something completely different that you guys suggested.
Took me whole day to make it :/
groups :: [Int] -> [Int]
groups list = [sum x | x <- makelist list]
makelist :: [Int] -> [[Int]]
makelist xs = reverse (foldl (\acc x -> zero x acc) [[]] xs)
zero :: Int -> [[Int]] -> [[Int]]
zero x acc | x == 0 = addnewtolist acc
| otherwise = addtolist x acc
addtolist :: Int -> [[Int]] -> [[Int]]
addtolist i listlist = (i : (head listlist)) : (drop 1 listlist)
addnewtolist :: [[Int]] -> [[Int]]
addnewtolist listlist = [] : listlist
Now that you’ve completed the problem on your own, I am showing you a slightly less verbose version.
Foldrseems better in my opinion to this problem*, but because you asked forfoldlI will show you my solution using both functions.Also, your example appears to be incorrect, the sum of [5,2,1] is 8, not 7.
The
foldrversion.In this version, we traverse the list, if the current element (x) is a 0, we add a new element to the accumulator list (n:ns). Otherwise, we add the value of the current element to the value of the front element of the accumulator, and replace the front value of the accumulator with this value.
Step by step:
acc = [0], x = 1. Result is [0+1]acc = [1], x = 2. Result is [1+2]acc = [3], x = 5. Result is [3+5]acc = [8], x = 0. Result is 0:[8]acc = [0,8], x = 4. Result is [0+4,8]acc = [4,8], x = 3. Result is [4+3,8]acc = [7,8], x = 0. Result is 0:[7,8]acc = [0,7,8], x = 3. Result is [0+3,7,8]acc = [3,7,8], x = 2. Result is [3+2,7,8]acc = [5,7,8], x = 1. Result is [5+1,7,8] = [6,7,8]There you have it!
And the
foldlversion. Works similarly as above, but produces a reversed list, hence the use of reverse at the beginning of this function to unreverse the list.*Folding the list from the right allows the cons (:) function to be used naturally, using my method with a left fold produces a reversed list. (There is likely a simpler way to do the left fold version that I did not think of that eliminates this triviality.)