The monoid identity property allows us to handle empty collections in a general way. So, instead of having the following:
def reduceLeft(op: (A, A) => A): A
We'll have a definition that takes an identity element as another parameter. By convention, this approach is called fold:
def foldLeft(identity: A)(op: (A, A) => A): A
The reason for the name foldLeft is that the identity element is used as an initial argument for reducing the collection, which leads to the following sequence of calls:
op(op(op(op(identity, a1), a2), a3), a4), ...
Optionally, it is represented in postfix-notation:
(((identity op a1) op a2) op a3) ...
Which is, well, kind of folding the collection, starting with the identity and the first element of it.
The associativity of the operation and the identity element tells us that another approach is also possible, starting from the identity...