fp-ts: How to combine multiple Option producers?

Viewed 642

I am looking for an fp-ts function that has this behavior:

function compute1(arg: number): Option<number>;
function compute2(arg: number): Option<number>;
function compute3(arg: number): Option<number>;

function compute(arg: number): Option<number> {
  const first = compute1(arg)
  if (isSome(first)) return first

  const second = compute2(arg)
  if (isSome(second)) return second

  const third = compute3(arg)
  if (isSome(third)) return third

  return none
}

// For example I am looking for this `or` function:
const compute = or([
  compute1,
  compute2,
  compute3,
])

I was not able to find a corresponding function in the documentation of Option here.

1 Answers

I think you are looking for getLastMonoid within the Option library. This will give you the right most some value as shown in the table below:

x y concat(x, y)
none none none
some(a) none some(a)
none some(a) some(a)
some(a) some(b) some(b)

However, this only helps you for pairs of Option, in order to apply it to an array of Option, you will need to rely on the reduceRight function inside Array. Similar to the reduce function inside vanilla javascript arrays, it will take an initial value B and pass it through a function funtil it has gone through the entire array.

Putting all this together, your compute function can be replaced with the below:

import { getLastMonoid, some, none, Option } from "fp-ts/lib/Option";
import { reduceRight } from "fp-ts/lib/Array";

import { pipe } from "fp-ts/lib/function";

const M = getLastMonoid<number>();

const list = [some(1), some(2), some(3)];

const compute = (list: Option<number>[]): Option<number> =>
  pipe(list, reduceRight(none, M.concat));

console.log(compute(list)); // some(3)
Related