I'm sure this is answered somewhere, but I don't have good enough search terms to find it. I am using the io.vavr.control.Try package, and when I try to use getOrElseThrow method on an element in a stream of results, the method is ambiguous with the io.vavr.Value class. Can I specify which method I want to use somehow, or is it impossible?
-
I don't think I was clear enough, or maybe I just don't understand the answers given. My main question is: generically, can I resolve ambiguity in method calls without editing either of the methods? If so, how do I tell the compiler which one to use? – EMC Oct 15 '19 at 20:28
3 Answers
You could replace NotFoundException::new
with t -> new NotFoundException(t)
which will only match the Function argument.

- 731
- 2
- 5
- 16
Since you didn't post complete code I can only make an educated guess about how your NotFoundException
looks like, but I think it contains at least two constructors in the following form:
public NotFoundException() {}
public NotFoundException(Throwable cause) {
super(cause);
}
If you want to use constructor method references with Try.getOrElseThrow
, you'll need to eliminate the method reference ambiguity by removing one of these constructors (or potentially reducing visibility), or fall back to using lambdas for constructing the resulting throwable.
If you cannot, or do not want to change the NotFoundException
class, you can either fall back to using a lambda instead of a method reference (1 and 2), or you can create explicit Function
(2) or Consumer
(3) instances with the help of the vavr function type factory methods:
rsp.getOrElseThrow(cause -> new NotFoundException(cause)); // (1)
rsp.getOrElseThrow(() -> new NotFoundException()); // (2)
rsp.getOrElseThrow(Function1.of(NotFoundException::new)); // (3)
rsp.getOrElseThrow(Function0.of(NotFoundException::new)); // (4)

- 6,988
- 1
- 22
- 47
You have a number of options:
Add an explicit cast to the desired type:
.map(rsp -> rsp.getOrElseThrow((Supplier<NotFoundException>) NotFoundException::new)) .map(rsp -> rsp.getOrElseThrow((Function<? super Throwable, NotFoundException>) NotFoundException::new))
Use a lambda expression instead of a method reference:
.map(rsp -> rsp.getOrElseThrow(() -> new NotFoundException())) .map(rsp -> rsp.getOrElseThrow(t -> new NotFoundException(t)))
Use an explicit type of the outer lambda parameter:
.map((Value<…> rsp) -> rsp.getOrElseThrow(NotFoundException::new)) .map((Try<…> rsp) -> rsp.getOrElseThrow(NotFoundException::new))

- 22,334
- 15
- 80
- 130