How to pattern match a tuple of Option with defined type in Java with Vavr

832 Views Asked by At

new Vavr user here. I am trying to pattern match a tuple of options to execute a statements if both of them are Some, in Scala I would have done this with:

val maybeThis: Option[String] = ???
val maybeThat: Option[String] = ???

(maybeThis, maybeThat) match {
  case (Some(dis), Some(that)) => ???
  case _ => ???
}

In Java, I am trying this approach:

Tuple2<Option<String>, Option<String>> tuple = new Tuple2<>(Option.of(...), Option.of(...));

return Match(tuple).of(
  Case($Tuple2($Some($(instanceOf(String.class))), $Some($(instanceOf(String.class)))),
                    (someThis, someThat) -> methodWhichEatsTwoStrings(someThis.get(), someThat.get())),
  Case($(), t -> run(() -> {
                throw new NullPointerException(...);
            })));

However, with this implementation the compiler complains that it was expecting Some<Object> instead of Some<String>, same error happens if I omit the $(instanceOf(String.class) in the pattern.

I am moderately sure this is merely a problem of proper syntax, yet I am struggling to find the correct documentation. Where am I wrong? Thanks

1

There are 1 best solutions below

0
On

There's a vavr API construct called for comprehension that tries to mimic Scala's for comprehensions to the extent that it's possible to do in Java. With that construct you could solve your problem quite elegantly. See the For overload for handling two Options for more details. Here's an example code snippet:

String methodWhichEatsTwoStrings(String v1, String v2) {
    return v1 + v2; //combine the two values in some way
}

...

Option<String> option1 = Option.some("value1");
Option<String> option2 = Option.some("value2");

String combined = For(option1, option2)
    .yield((v1, v2) -> methodWhichEatsTwoStrings(v1, v2))
    .getOrElseThrow(() -> new NullPointerException("reasons"));

Of course, you could use Option wrapping values of different types for option1 and option2, or combine multiple options, not just two. You could also use a different type for the return value of the yield function as well. I used String everywhere for the sake of simplicity and to conform to your original example.

I would like to add that I would try to avoid throwing NullPointerException in case one or both of the options are empty. Maybe try to use another vavr data type like Either to represent such an error case?