This is one of the most straightforward ways of thinking about folds on lists.
Remind yourself of the most common definition of a fold:
I will make one change - instead of f
, we will use the operator (which signifies the same thing, simply infix). Therefore, we get:
Let’s apply this - in the most general case - to a finite list.
Using the definition of foldr
, we get:
This is the idea of a fold as being repeated operator application. This metaphor applies mostly to lists (because we can use an infix operator), but can be tweaked for other recursive data structures.
However, this metaphor can obscure two related facts about folds.
First: Haskell is lazy. It is not necessarily true that all the parentheses will be calculated. For example:
This function returns true if any value in the list passed to it is True. Otherwise it returns false. But the operator (||)
is lazy (it short-circuits):
Instead we get to:
Second: Folds work on infinite lists.
Of course, isFive
halts after 5
. But say we run isFive [6..]
- it will never return. Noticing that we can do folds on infinite instances of data structures is related to lazyness - but using this as a frame can obscure that.