Search code examples
javascalafunctional-programmingvavr

Extracting first defined value(if any) from sequence of suppliers of optional values


Given a sequence of Supplier<Option<T>> -- e.g., a list of method references -- what's the idiomatic way to get the first defined result, if any? Ideally without invoking any more suppliers after the first successful result.

What I have now is:

Stream<Supplier<Option<Foo>>> suppliers = Stream.of(
  bar::fooOption,
  baz::fooOption,
  qux::fooOption
);

Option<Foo> firstDefined = suppliers.map(Supplier::get)
  .find(Option::isDefined)
  .flatMap(Function.identity());

but it seems like there ought to be a way to flatmap that 💩 even flatter.


Solution

  • I can only see an alternative solution with equal number of steps as yours.

    Option<Foo> firstDefined = suppliers.map(Supplier::get)
            .find(Option::isDefined)
            .map(Option::get);
    

    If you can do with a simple map instead of a flatMap, use that instead, as it will be usually faster, especially on multi-valued monadic containers. There's probably not much difference though for 0/1 valued monads, like Option, perhaps on the contrary, it might be a tad slower in this case, as it creates an additional Option.