foldl :: (a -> b -> a) -> a -> [b] -> a
foldl step zero (x:xs) = foldl step (step zero x) xs
foldl _ zero [] = zero
I don’t quite understand why does (a -> b -> a) return a, also (a -> b -> a) -> a -> [b] -> a return a. I would think it should be like: (a -> b -> c) -> a -> [b] -> c. Can someone explain that to me based on the example below. Thanks!
foldl (+) 0 (1:2:3:[])
foldl (+) (0 + 1) (2:3:[])
foldl (+) ((0 + 1) + 2) (3:[])
foldl (+) (((0 + 1) + 2) + 3) ([])
foldl (+) (((0 + 1) + 2) + 3)
arepresents the type of the accumulator value, andbrepresents the type of each element in the input.(a -> b -> a)is a function that takes an accumulator value, some item in the list, and returns a new accumulator value that can be passed onto the next step.The type of the initial value must be
aso that the first invocation of the function can receive an accumulator value. The accumulator function must take anaand return anaso that an accumulator value can be passed to each step of the fold. The final value of the fold must necessarily be ana, because that is the type of the accumulator that will be returned by the final call the fold function.(a -> b -> c) -> a -> [b] -> ccannot represent a fold, because the folding function does not take ac. The input and output of the folding function must be the same type so the accumulator can be passed to the next fold step.Let’s see an example of what would happen if the fold function returned a
c.Pretend we’re using a dynamic language and we try to fold with
f. What happens at runtime?You can see that you can’t make a fold work if you try to accumulate with incompatible types.