DEV Community

Iven Marquardt
Iven Marquardt

Posted on • Edited on

2 2

Composing binary functions with a fixed return type - wait, what?

Functonal programming is about composition. Ordinary composition of single-argument functions is trivial. It gets more interesting if we try to combine more complex function types of the real world. What about composing functions that compare two values and return a comparator?

First we don't want to rely on the 1/0/-1 comparator protocol but on a real tagged union:

const Comparator = union("Comparator");

const LT = Comparator("LT", {valueOf: () => -1});

const EQ = Comparator("EQ", {valueOf: () => 0});

const GT = Comparator("GT", {valueOf: () => 1});

// monoid instance

const ctorEmpty = () => EQ;

const ctorAppend = tx => ty => 
  match(tx, {
    LT: _ => LT,
    EQ: _ => ty,
    GT: _ => GT
  });
Enter fullscreen mode Exit fullscreen mode

Next we need a Compare type for functions that return a Comparator:

const Compare = cmp => record(Compare, {cmp});

// monoid instance

const cmpEmpty = () => _ => _ => ctorEmpty();

const cmpAppend = tx => ty =>
  Compare(x => y => ctorAppend(tx.cmp(x) (y)) (ty.cmp(x) (y)));
Enter fullscreen mode Exit fullscreen mode

Now we can combine several Compare based functions to define more complex comparing rules. We can do this because we implemented the monoid instances for both types:

const isEven = x => (x & 1) === 0;

const byNatural = Compare(x => y =>
  x < y ? LT
    : x > y ? GT
    : EQ);

const byEven = Compare(x => y =>
  isEven(x) && !isEven(y) ? GT
    : !isEven(x) && isEven(y) ? LT
    : EQ);

const xs = [4, 8, 2, 5, 3, 9, 6, 1, 7, 0];

xs.sort(
  (x, y) =>
    cmpAppend(byEven)
      (byNatural).cmp(x) (y)); // [1, 3, 5, 7, 9, 0, 2, 4, 6, 8]
Enter fullscreen mode Exit fullscreen mode

run code

We use a destructive sort function, but that is okay for the time being.

Heroku

Build apps, not infrastructure.

Dealing with servers, hardware, and infrastructure can take up your valuable time. Discover the benefits of Heroku, the PaaS of choice for developers since 2007.

Visit Site

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay