DEV Community

Iven Marquardt
Iven Marquardt

Posted on

3

FP serves the most delicious abstractions

For instance, if we try to combine two composed applicatives of type Task<Option<number[]>, E> - an async computation that may fail or yields any number of numbers - it gets pretty soon pretty ugly:

// tAp/tMap     = Task functor/applicative
// optAp/optMap = Option functor/applicative
// arrAp/arrMap = Array functor/applicative
// tttx         = Task(Some([1,2,3]));
// ttty         = Task(Some([10,20,30]));

tAp(
  tMap(x_ => y_ =>
    optAp(
      optMap(x => y =>
        arrAp(
          arrMap(add) (x)) (y)) (x_)) (y_))
            (tttx))
              (ttty); // Task(Some([11,21,31,12,22,32,13,23,33]))
Enter fullscreen mode Exit fullscreen mode

We can get rid of the anonymous functions by using point-free style, but the computation still remains hideous and confusing:

const comp = f => g => x => f(g(x));

tAp(
  tMap(
    comp(optAp)
      (optMap(
        comp(arrAp) (arrMap(add)))))
          (tttx))
            (ttty); // Task(Some([11,21,31,12,22,32,13,23,33]))
Enter fullscreen mode Exit fullscreen mode

The problem seems to be the common applicative pattern ap(map(f) (x)) (y). Let's abstract it:

const liftA2 = ({map, ap}) => f => tx => ty =>
  ap(map(f) (tx)) (ty);

const tLiftA2 = liftA2({map: tMap, ap: tAp});
const optLiftA2 = liftA2({map: optMap, ap: optAp});
const arrLiftA2 = liftA2({map: arrMap, ap: arrAp});

comp3(
  tLiftA2)
    (optLiftA2)
      (arrLiftA2)
        (add)
          (tttx)
            (ttty); // Task(Some([11,21,31,12,22,32,13,23,33]))
Enter fullscreen mode Exit fullscreen mode

This is much better. comp3 takes three functions and the resulting composed function takes add and two composed values tttx/ttty and applies add to the inner values. Since applicative computation of the Array type means to calculate the cartesian product this is what we get. Nice.

See an running example and how everything falls into place.

If you want to learn more about FP join my course on Github.

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

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