F2.05 · part 4 of 4
Advanced folds
Once reduce is clear, the rest of the Enum toolkit reads as folds with
extra structure. Scan keeps every intermediate result; map_reduce maps and accumulates at once; flat_map,
group_by, and chunk only choose a different accumulator shape.
Reduce throws away every intermediate accumulator and returns the last one. Many useful operations want those intermediates, or a second value alongside the result, or a particular grouping. Each is a small variation on the same left-to-right fold — worth recognising so you reach for the packaged one instead of rebuilding it.
scan: a running fold
Reduce returns only its final accumulator. Scan returns all of them — one entry per element, each the accumulator so far. Folding addition with reduce gives the total; with scan it gives the running totals.
Step through and watch the running list build.
- scan
- a fold that emits every intermediate accumulator, not only the last.
- running fold
- the sequence of accumulators as the fold proceeds.
- map_reduce
- map and accumulate in a single pass, returning both.
- group_by
- fold into a map from a key to the elements sharing it.
scan([1, 2, 3, 4], &+/2) · reduce keeps the last; scan keeps them all
Idea
Keep the intermediates and a fold becomes a history, not only a total.
Elixir
Enum.scan/2 for running totals; Enum.reduce/3 for the final one.
Scan is reduce that remembers its work: the same combiner, every accumulator kept.
The toolkit
Five common operations, each a fold with a twist: a second return value, a flattened result, a grouping, a tally, or fixed-size batches. Knowing they are folds tells you they each make one left-to-right pass.
Browse the toolkit.
Enum operations · folds with extra structure
Idea
Each is reduce with a chosen accumulator shape and a final touch.
F2 · Functional
Reach for the named operation; fall back to reduce when none fits.
The Enum module is mostly folds with names. Reduce is the floor; these are the conveniences built on it.
Where this goes
That completes F2.05. A fold threads an accumulator down a list; map and filter are folds with a list accumulator; reduce is the general one, taking an accumulator of any shape; and the wider Enum toolkit is folds with extra structure. The combiners these folds take are usually small functions that capture a value from their surroundings — which is exactly what F2.06 is about.
Next: F2.06 — Closures & partial application — capturing environment, and currying by hand. Back to the F2.05 hub or the F2 overview.