Sure!
I was confused when the book says “foldr
folds right-to-left”, then goes on to say “foldr
can work on infinite lists”. Since infinite lists have no right, this doesn’t seem to make sense. Where does it start?
The confusion (I think) comes from what we think of as “starting”.
foldr
builds up a set of function calls from right-to-left, like so:
-- Generically
x = foldr f z [1, 2, 3]
x = f 1 (f 2 (f 3 z))
-- A concrete example
sum = foldr (+) 0 [1, 2, 3]
sum = (+) 1 ((+) 2 ((+) 3 0))
-- Again, but written as infix
sum = 1 + (2 + (3 + 0))
You’ll notice that this indeed “starts” on the right with (+) 3 0
and folds “to the left” applying your function to each successive result in an outward fashion.
Since haskell is lazy, the evaluation of the functions will start on the left.
sum = 1 + (... + (... + (... + ...
And if the function used doesn’t always need to evaluate its second argument, it simply never will. If this were the case, the ...
above wouldn’t matter and thus, could be infinite. The example the author uses is (&&)
folded over an infinite list of False
values.
A left fold, on the other hand, folds left-to-right:
sum = foldl (+) 0 [1, 2, 3]
sum = ((0 + 1) + 2) + 3
Think about (lazily) evaluating this function and convince yourself that it can’t do anything until it finds the end of the list:
sum = ... + ...) + ...) + ...) + ?