पाठ 10 / 25
Function Composition and Pipelines
compose and pipe.
Joining functions end to end
Composing f and g gives a new function x => f(g(x)): apply g, then f. compose(f, g, h) applies functions right to left, matching mathematical notation; pipe(h, g, f) applies them left to right, which usually reads better. Composition works best with unary functions whose output type matches the next input type. Libraries such as Ramda, lodash/fp and fp-ts provide these helpers; a JavaScript pipeline operator |> has been proposed but is not part of the language at the time of writing, so check the TC39 proposal status. In Haskell, composition is the built-in . operator.
Building big functions from small ones
Composition connects the output of one function to the input of the next, so programs read as pipelines.
A tiny pipe helper
Typed for a uniform type to keep the example short.
const pipe = <T>(...fns: Array<(x: T) => T>) =>
(x: T): T => fns.reduce((acc, fn) => fn(acc), x);
const compose = <T>(...fns: Array<(x: T) => T>) =>
(x: T): T => fns.reduceRight((acc, fn) => fn(acc), x);
const trim = (s: string) => s.trim();
const lower = (s: string) => s.toLowerCase();
const collapseSpaces = (s: string) => s.replace(/ +/g, ' ');
const normalise = pipe(trim, lower, collapseSpaces);
// normalise(' Hello World ') evaluates to 'hello world'
const normalise2 = compose(collapseSpaces, lower, trim); // same resultComposition in Haskell
Haskell composes with the built-in . operator, right to left: normalise = map toLower . unwords . words splits on whitespace, rejoins with single spaces, then lowercases (with toLower imported from Data.Char).
त्वरित जाँच: In what order does `pipe(a, b, c)(x)` apply the functions?
- `a` first, then `b`, then `c`
- `c` first, then `b`, then `a`
- All three in parallel
- Only `a`; the others are ignored
Answer
`a` first, then `b`, then `c` — pipe reads left to right; compose reads right to left.