Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
December 30, 2021 11:15 pm GMT

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);const congaReadyBar = B(bar);const congaLine = congaReadyFoo(congaReadyBar(baz));// 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 farconst congaLine = B(foo)(B(bar)(baz))

This is mainly due to the syntax being hard to follow though as when it's an operator it's much easier:

congaLine = foo . bar . baz 

There's many more fun combinators but I wanted to start here to start somewhere.

Bonus fact: B turns functions themselves into a functor

class Functor f where  fmap :: (a -> b) -> f a -> f binstance 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.


Original Link: https://dev.to/jethrolarson/beautiful-functions-compose-4ce3

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To