0

I am looking for a way to chain functions together similar to overSome or flow within lodash.

This is the comparable function written out.

const e = async ({planGroups, uuid, name, user, organization}) => {
  const a = this.getPlanGroupByUuid({ planGroups, uuid })
  if (a) return a
  const b = this.getPlanGroupByName({ planGroups, name })
  if (b) return b
  const c = await this.createPlanGroup({ name, user, organization })
  return c
}

e({planGroups, uuid, name, user, organization})

This would be the compositional version.

const x = await _.overSome(this.getPlanGroupByUuid, this.getPlanGroupByName, this.createPlanGroup)

x({planGroups, uuid, name, user, organization})

The idea is that the function returns the first function with a truthy value.

Is this possible within lodash alone? Is there a better compositional function library with typescript support?

ThomasReggi
  • 55,053
  • 85
  • 237
  • 424
  • 1
    I think this is a perfect use case for a Maybe/Option monad. I'd recommend checking out `fp-ts`, `purify-ts`, or similar. In the case of `fp-ts`, you'll probably need to use `Option`, `pipe`, `chain`, and if there's async in the mix then `Task`. – Sam A. Horvath-Hunt Sep 06 '19 at 18:39

1 Answers1

1

You can do this with ramda. Example:

const composeWhileNotNil = R.composeWith(async (f, res) => {
  const value = await res;
  return R.isNil(value) ? value : f(value)
});


const getA = x => x * 2
const getB = x => Promise.resolve(x * 3)
const getC = x => x * 10


async function run(){
  const result = await composeWhileNotNil([getC, getB, getA])(1);
  console.log("result:", result); // result: 60
}

run();

If you prefer left-to-right composition, you can use pipeWith.

Working example: https://repl.it/repls/TemptingAridGlitch

adrice727
  • 1,482
  • 12
  • 17
  • I can not get the typing to work correctly for this example. I am also looking for a simple function that behaves similar to `_.flow` where I can get a properly typed return function. – ThomasReggi Sep 07 '19 at 01:12