2

I'm trying to return Either value depending on option value. My goal is to return Either.right() if the option is present otherwise, the code should return Either.left(). I use Java 8 and vavr 0.9.2

I want to avoid conditional imbrication

public Either<String, Integer> doSomething() {
    Optional<Integer> optionalInteger = Optional.of(Integer.MIN_VALUE);
    Option<Integer> integerOption = Option.ofOptional(optionalInteger);

    return integerOption.map(value -> {
      //some other actions here
      return Either.right(value);
    }).orElse(() -> {
      //some other checks her also 
      return Either.left("Error message");
    });
}

the compiler fail with this message

Error:(58, 7) java: no suitable method found for orElse(()->Either[...]age"))
    method io.vavr.control.Option.orElse(io.vavr.control.Option<? extends io.vavr.control.Either<java.lang.Object,java.lang.Integer>>) is not applicable
      (argument mismatch; io.vavr.control.Option is not a functional interface
          multiple non-overriding abstract methods found in interface io.vavr.control.Option)
    method io.vavr.control.Option.orElse(java.util.function.Supplier<? extends io.vavr.control.Option<? extends io.vavr.control.Either<java.lang.Object,java.lang.Integer>>>) is not applicable
      (argument mismatch; bad return type in lambda expression
          no instance(s) of type variable(s) L,R exist so that io.vavr.control.Either<L,R> conforms to io.vavr.control.Option<? extends io.vavr.control.Either<java.lang.Object,java.lang.Integer>>)
Lakshan Dissanayake
  • 521
  • 1
  • 4
  • 18
EFOE
  • 609
  • 1
  • 10
  • 20

4 Answers4

8

orElse returns Option<T> while doSomething return type requires Either<String, Integer>.

Instead, try to use getOrElse which returns T:

public Either<String, Integer> doSomething() {
    // ...
    return integerOption.map(
        Either::<String, Integer>right).getOrElse(
            () -> Either.left("Error message"));
}
Oleksandr Pyrohov
  • 14,685
  • 6
  • 61
  • 90
  • Thanks for your answer but with getOrElse, there is no way to infer Either it always infers Either Error:(59, 17) java: incompatible types: io.vavr.control.Either cannot be converted to io.vavr.control.Either – EFOE Jun 08 '19 at 21:52
  • 2
    Yes, that's why you need to provide an explicit type argument: `Either::right`, no matter it is `getOrElse` or `orElse`. – Oleksandr Pyrohov Jun 08 '19 at 22:17
  • I believe it's called `orElseGet`, not `getOrElse` in java ;) – Klesun Jun 04 '20 at 14:43
  • 1
    @Klesun No, as it's a [vavr api method](https://www.javadoc.io/doc/io.vavr/vavr/0.9.2/io/vavr/control/Option.html#getOrElse-T-). – Oleksandr Pyrohov Nov 27 '20 at 15:14
0

Since you want to return Either<...> not an Option<Either<...>> you have to use getOrElse

adil.hilmi
  • 197
  • 5
0

I think redundant generics and formatting in @oleksandr-pyrohov's answer overcomplicate things a bit. I'd just write it this way instead:

public Either<String, Integer> doSomething() {
    // ...
    return integerOption
        .map(Either::right)
        .orElseGet(() -> Either.left("Error message"));
}

Upd.: though it does not seem to always infer generics on it's own sadly.

Klesun
  • 12,280
  • 5
  • 59
  • 52
0

It works for me

public Either<String, Integer> doSomething() {
// ...
return integerOption
    .<Either<String, Integer>>map(Either::right)
    .orElseGet(() -> Either.left("Error message"));
}
luprogrammer
  • 155
  • 1
  • 3
  • 12