Split a list and make an amount from a sublist?

im looking for a solution for my Haskell class.

I have a list of numbers, and I need to return SUM for each part of the list. Parts are divided by 0. I need to use the 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 to find 0 in the source list:

findPos list = [index+1 | (index, e) <- zip [0..] list, e == 0] 

(returns the source list from the example) [4,6]

and function to create SUM with FOLDL:

sumList list = foldl (+) 0 list

But I was completely unable to collect it: /

---- MY DECISION
In the end, I found something completely different that you guys suggested.
Took me all day to do this: /

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
+5
source share
3 answers

, , . Foldr , , *, foldl, , .

, , [5,2,1] 8, 7.

Foldr.

makelist' l = foldr (\x (n:ns) -> if x == 0 then 0:(n:ns) else (x + n):ns) [0] l

, (x) 0, (n: ns). .

:

  • 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]

!

foldl. , , .

makelist l = reverse $ foldl (\(n:ns) x -> if x == 0 then 0:(n:ns) else (x + n):ns) [0] l

* cons (:) , , . (, , , .)

+2

, , , .

, . ( ) ; :

splits []     = {- ... -}
splits (0:xs) = {- ... -}
splits (x:xs) = {- ... -}

groupBy, .

, , ; , map :: (a -> b) -> ([a] -> [b]), .

, . - , , foldr/foldl !

:

, , , . =)

; , , , . :

splits []     = []
splits (0:xs) = [] : splits xs
splits (x:xs) = case splits xs of
    []       -> [[x]]
    (ys:yss) -> ((x:ys):yss)

groups' = map sum . splits

:

splits' = groupBy (\x y -> y /= 0)
groups'' = map sum . splits'

all-at-once :

accumulate 0 xs     = 0:xs
accumulate n (x:xs) = (n+x):xs

groups''' = foldr accumulate [0]

, , , :

  • splits splits' [1,2,3,0,4,5]? [1,2,0,3,4,0]? [0]? []? ghci.
  • , groups ( ) [] [1,2,0,3,4,0], ghci.
  • groups''', .
  • groups''', foldl foldr.
+6

As you have already decided, another version:

subListSums list = reverse $ foldl subSum [0] list where
   subSum xs 0 = 0 : xs
   subSum (x:xs) n = (x+n) : xs

(Assume that the list contains only non-negative numbers)

+1
source