# Function Composition and Pipelines — Functional Programming Concepts

Source: https://www.geekswithgeeks.com/en/functional-programming/cp-compose

> 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.

![Three ideas: compose and pipe, currying and partial application, point-free style.](assets/figures/functional-programming/section-4-map.svg) — Figure 4.1 — Small functions joined into a pipeline.

## A tiny pipe helper

Typed for a uniform type to keep the example short.

```typescript
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 result
```

## Composition 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`).

**Quiz:** In what order does `pipe(a, b, c)(x)` apply the functions?

- [x] `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.
