flatMap combines a transformation with a flattening step. On a JavaScript array, it is the common `map`-then-`flat` sequence in one operation: a callback produces values, and the result does not retain the extra array layer created by mapping. Like `flat`, it returns a new array rather than changing the original. section 5.2.2 section 5.2
Replace a nested intermediate array
When each block contains an array of transactions, `.map(prop('data')).flat()` first creates an array of transaction arrays. `.flatMap(prop('data'))` expresses the same step directly, leaving one array of transactions for the later balance calculation. section 4.7
Listing 4.16 computeBalance using map, filter, and reduce
function computeBalance(address, ledger) {
return Array.from(ledger)
.filter(not(prop('isGenesis')))
.flatMap(prop('data')) #1
.map(balanceOf(address))
.reduce(Money.sum, Money.zero())
.round();
}
The balance pipeline filters blocks, flat-maps their transaction data, converts transactions to monetary effects, and reduces those effects to a total. section 4.7
The idea extends beyond arrays. Mapping a function that returns a container can produce a container inside another container. A monad supplies `flatMap` to compose such functions without retaining that extra wrapping. For a simple `Id` container, the shown implementation uses `this.map(f).get()`; `chain` and `bind` are alternative names. This is contextual composition: the container participates in how successive functions connect. section 5.4.2 section 5.2.2
Choose the form that matches the work:
- Use array `flatMap` when a mapping step would otherwise be followed by `flat`; it also avoids the separate intermediate result of those two calls. section 4.7 section 5.4.2
- Use a container’s `flatMap` when each function returns another instance of that container and the computations must remain chainable. section 5.4.2
With `Validation`, the context is success or failure. A successful result can continue through `flatMap`; a failure skips subsequent checks and propagates its error. This keeps validation in the chain instead of interleaving each operation with `if/else` or `try/catch`. Paired with `reduce`, `flatMap` can also collapse validation across a nested structure to one result. section 5.5.3 section 5.5.7
Listing 5.23 HasValidation mixin
const HasValidation = () => ({
validate() {
return [...this] #1
.reduce((validationResult, nextItem) => #2
validationResult.flatMap(() => nextItem.validate()),
this.isValid() #3
);
}
});
The reducer starts with an object’s validation result and flat-maps each subsequent item’s validation into that result. section 5.5.7




