# Calculate sum and length of a list simultaneously with foldl and a tuple

• A+
Category：Languages

I've been struggling with foldr for a while now. i want to convert a list of ints to a single tuple that contains the sum of list and number of ints. for example [1,2,3,4] -> (10,4) the function i have below iterates through the list fine but only outputs the last element as the x val and 1 as the y val.

``toTuple xs = let tuple = foldl (/a b -> ((sum1 + b),(len1 + 1))) (0.0,0.0) xs                in tuple                   where sum1 = 0                      len1 = 0   ``

i originally had sum1 and len1 as functions that take in an single int as an input but that didnt' work either so i changed them to variables initailized to 0. however it seems like its setting sum and len to 0 at every element in the list. any suggestions to modify this? thanks!

It looks like you haven’t built an intuition for folds yet. You can think of a fold like `foldl combine start input` as starting with some `start` value, then combining that value with each element of the `input` using the `combine` function. The function accepts the current “state” and the next element of the list, and returns the updated state. So you are very close to a working solution:

``toTuple xs = foldl (/ (sum, len) x -> (sum + x, len + 1)) (0, 0) xs ``

Stepping through an example input like `[1, 2, 3, 4]`, the state `(sum, len)`, usually called an “accumulator”, takes on the following values each time the folding function is called:

``(0, 0) (0+1, 0+1)             = (1, 1) (0+1+2, 0+1+1)         = (3, 2) (0+1+2+3, 0+1+1+1)     = (6, 3) (0+1+2+3+4, 0+1+1+1+1) = (10, 4) ``

At no point are we modifying any variables, just calculating the next value of the sum and the length by combining the current partial sum & length with each element of the list. For a left fold (`foldl`) that’s done from left to right; for a right fold (`foldr`) it’s from right to left, so the order of the parameters (`(sum, len)` and `x`) is reversed:

``toTuple xs = foldr (/ x (sum, len) -> (sum + x, len + 1)) (0, 0) xs ``

However, for right folds, I find it easier to think of them as replacing all the `:` in a list with a function and replacing the `[]` with a value:

``foldr f z [1, 2, 3, 4] foldr f z (1 : (2 : (3 : (4 : [])))) 1 `f` (2 `f` (3 `f` (4 `f` z))) ``