We can create a
pipe function by creating a function that takes an array of functions as arguments.
It returns a function that takes a value and we call
reduce on it with that calls
For example, we can write:
const compose = (...fns) => (value) => fns.reduceRight((acc, fn) => fn(acc), value)
The only difference is that we used
reduceRight instead of
reduce so that we don’t have to call
reverse to apply all the functions.
Composition is associative, this means we can rearrange the parentheses of our operations
compose(f, compose(g, h)) == compose(compose(f, g), h)