I think it's a flawed characterization. It's better to think of fold like this:
In:
initial value
way to combine stuff with initial value
collection
Out:
combined stuff
And reduce is like this:
In:
way to combine stuff
collection
Out:
combined stuff
That is, the difference is whether you have an initial value (which might not even be of the same type as what you've got in the collection!), as fold does, or whether you just collapse the values you already have, as reduce does.
If you have a natural zero, that is, something that can be combined without changing what it combines with, then you can implement reduce as a fold starting with a zero. For example, for multiplication the zero is 1
(because 1*x == x
), so
List(1,2,3).fold(1){_ * _}
List(1,2,3).reduce{_ * _}
give the same answer. (Only the first gives an answer on an empty list, however!)
To see an example of how fold is entirely more general, consider this one--here with a foldLeft so we know to pass the initial value in on the left-hand side of the operation--
List(1,2,3).foldLeft(List(0))((ns,n) => ns ++ List.fill(n+1)(n))
which gives List(0, 1, 1, 2, 2, 2, 3, 3, 3, 3)
.