Option<>.collect() not to call PartialFunction on args where it is not defined #2580
Add this suggestion to a batch that can be applied as a single commit. This suggestion is invalid because no changes were made to the code. Suggestions cannot be applied while the pull request is closed. Suggestions cannot be applied while viewing a subset of changes. Only one suggestion per line can be applied in a batch. Add this suggestion to a batch that can be applied as a single commit. Applying suggestions on deleted lines is not supported. You must change the existing code in this line in order to create a valid suggestion. Outdated suggestions cannot be applied. This suggestion has been applied or marked resolved. Suggestions cannot be applied from pending reviews. Suggestions cannot be applied on multi-line comments. Suggestions cannot be applied while the pull request is queued to merge. Suggestion cannot be applied right now. Please check back later.
Fixes ##2579
Expected behavior: Option<>.collect() calls PartialFunction passed as argument only for the value on which this PartialFunction is defined.
Observed behavior: PartialFunction called on values for which it is not defined, resulting in undesired behavior (i.e. unchecked exception thrown).
Example code which fails with arithmetic exception (division by zero):
Using io.vavr:vavr:0.10.2
I've checked the code and this is what I've found:
Optiona<>.collect() eventually calls PartialFunction.lift(), here
vavr/src/main/java/io/vavr/control/Option.java
Line 288 in 0b7a72c
in turn, PartialFunction.lift() looks like this:
default Function1<T, Option> lift() {
return t -> Option.when(isDefinedAt(t), apply(t));
}
— meaning
apply(t)will be always called, no matter ifisDefinedAt(t)returnstrueorfalse.vavr/src/main/java/io/vavr/PartialFunction.java
Line 126 in 0b7a72c
The proposed fix: changing the code to