## DEV Community 👩‍💻👨‍💻

Jethro Larson

Posted on • Updated on

# Beautiful Functions: Compose

I'd like to take a look at some functions whose form and function are the epitome of elegant.

The B combinator, sometimes called "compose":

``````const B = (f) => (g) => (x) => f(g(x))
``````

Which has the type:
`(b -> c) → (a -> b) → a → c`

in TypeScript:

``````const B = <A, B, C>(g: (y: B) => C) =>
(f: (x: A) => B) =>
(a: A): C =>
g(f(a));
``````

What it does is combine two unary functions (single-argument functions) together such that the output of the second is the input of the first. This is the core of composing functions in math as well as programming. If you have a couple procedures you want to link and sequence consider using this operator to do so.

``````const armTheMissiles = (missles: Missle[]): Missle[] => {...}

const fireTheMissles = (missles: Missle[]): void => {...}

const armAndFireMissles = B(fireTheMissles)(armTheMissles)
``````

This is such a core way of writing code that advanced languages like Haskell and F# have operators dedicated to it: `.` and `<<`, respectively.

``````armAndFireMissles = fireTheMissles . armTheMissles
``````

An easy place to integrate this function into your code is in cases where you take a callback that calls a function with it's parameters.

``````const fetchStuff = () =>
fetch(...).then(data => parseData(validate(data)))
``````

In this case you can use the B combinator to drop the inner lambda:

``````const fetchStuff = () =>
fetch(...).then(B(parseData)(validate))
``````

This way of eliminating lambdas by using composition techniques is called eta-reduction.

It may help to have an idea of what a partially applied `B` means. I like to think of it as the function has its arms out and is ready for the conga line.

``````const congaReadyFoo = B(foo);
// where foo, bar, and baz are all unary functions with compatible inputs and outputs.
``````

That all said, it's easy to go too far with this kind of technique.

``````// probably too far
const congaLine = B(foo)(B(bar)(baz))
``````

This is mainly due to the syntax as when it's an operator it's much easier to follow (haskell):

``````congaLine = foo . bar . baz
``````

There's many more fun combinators but I wanted to start with one many people may already be familiar with from high school math.

## Bonus fact: `B` turns functions themselves into a functor

``````class Functor f where
fmap :: (a -> b) -> f a -> f b

instance Functor ((->) r) where
fmap = (.)
``````

That is, given a function from `a -> b`, our compose function takes a function which takes something of type `a` and returns a function which takes something of type `b`. This means it's totally cool to think of composition as mapping a function over another function. Peter Franken

Very good explanation!

I never really understood or even cared about the concept until I saw it used in production (all those wasted years!). If you have time, maybe add a real-world practical use example for stragglers like me 😉 I showed one which is

``````const fetchStuff = () =>
fetch(...).then(data => parseData(validate(data))
``````

to

``````const fetchStuff = () =>
fetch(...).then(B(parseData)(validate))
``````

## Build Anything... Use any Linode offering to create something for the DEV x Linode Hackathon 2022. A variety of prizes are up for grabs, inculding \$1,000 USD. 👀

Join the Hackathon <-