Tonny Tc
Tonny Tc

Reputation: 930

Unexpected return type of vavr's Either in reactor

There are two simple methods using vavr's Either.

public Either<String, Integer> testEither(int s) {
    if (s == 0)
        return Either.left("Wrong");
    return Either.right(s);
}

public Mono<Either<String, Integer>> testReactorEither(int s) {
    return Mono.just(s).filter(x -> x == 0).map(Either::right)
            .switchIfEmpty(Mono.just(Either.left("ERROR")));
}

The testEither works normally, but meanwhile, the testReactorEither raises a compile error of "incompatible types" which says the provided return type of reactor.core.publisher.Mono<io.vavr.control.Either<java.lang.Object,java.lang.Integer>> is incompatible with required return of reactor.core.publisher.Mono<io.vavr.control.Either<java.lang.String,java.lang.Integer>>.

I'm afraid the problem is just because the method of map(Either::right) just defines the Right type of Integer but not do the Left type, and then the return type of the method is Either<?, Integer>. Then the question is how I can get the expected return type in this case?

[UPDATED]

As Hinse mentioned in his comment, the issue is related to the limitation of Java type inference, and some links I found for the problem is listed as follows:

https://bugs.eclipse.org/bugs/show_bug.cgi?id=511252

https://e.printstacktrace.blog/java-type-inference-generic-methods-chain-call/

https://openjdk.java.net/jeps/101

Upvotes: 1

Views: 1201

Answers (1)

Hinse ter Schuur
Hinse ter Schuur

Reputation: 390

The second example seems to 'lose' the type information for the left side when the map(Either::right) is applied.

Adding some type 'hints' to the map method call should do the trick. So the testReactorEither will look like this:

public Mono<Either<String, Integer>> testReactorEither(int s) {
    return Mono.just(s)
            .filter(x -> x == 0)
            .<Either<String, Integer>>map(Either::right)
            .switchIfEmpty(Mono.just(Either.left("ERROR")));
}

Upvotes: 1

Related Questions