From what I understand about folds in Haskell, foldl (-) 0 [1..5]
gives a result of -15
by calculating 0-1-2-3-4-5
, and foldr (-) 0 [1..5]
gives a result of -5
by calculating 5-4-3-2-1-0
. Why is it then that both foldl (++) "" ["a", "b", "c"]
and foldr (++) "" ["a", "b", "c"]
give a result of "abc"
, and the result of foldr
is not, instead, "cba"
?
Is there something I'm missing in understanding the differences between foldl
and foldr
?
I think this part from the docs makes it clearer:
In the case of lists, foldr, when applied to a binary operator, a starting value (typically the right-identity of the operator), and a list, reduces the list using the binary operator, from right to left:
foldr f z [x1, x2, ..., xn] == x1 `f` (x2 `f` ... (xn `f` z)...)
. . .
In the case of lists, foldl, when applied to a binary operator, a starting value (typically the left-identity of the operator), and a list, reduces the list using the binary operator, from left to right:
foldl f z [x1, x2, ..., xn] == (...((z `f` x1) `f` x2) `f`...) `f` xn
If you look at the example breakdown, the concatenation foldr
is equivalent to:
"a" ++ ("b" ++ ("c" ++ ""))
And for foldl
, it would be equivalent to:
(("" ++ "a") ++ "b") ++ "c"
For string concatenation, these are the same.
For subtraction however,
1 - (2 - (3 - 0))
Gives a different result than:
((0 - 1) - 2) - 3