jonnifyelixir
F2 / F2.05 / advanced

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

1 / 4
input running totals reduce would keep only 10


      
step 1 · first total is 1 · running [1]

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

accumulator the mapped list + an accumulator does maps and accumulates in one pass, returning both


      
map_reduce · map and accumulate at once · returns {mapped, acc}

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.