After calling map on a Some instance with a callback that returns null, the resulting Option object is still a Some instance.
Option.of("Hello World").map(s -> null) // results in Some(null) not None()
From my point of view it seems to be wrong or is it implemented in Scala in the same way?
May be the implementation of map method should changed to something like following snippet?
@Override
default <U> Option<U> map(Function<? super T, ? extends U> mapper) {
Objects.requireNonNull(mapper, "mapper is null");
return Option.of(mapper.apply(get()));
}
It is ok. Once a value is captured by a state (Some/present or None/empty), the map method has to preserve that state.
Scala does behave the same:
scala> Some(1).map(_ => null)
res1: Option[Null] = Some(null)
Option has to act like this because it follows the Functor laws.
And yes, it makes sense that there is a Some(null) :-) There are a few use-cases where this is needed. (See a recent discussion)
I will close this issue.
@manu-m I wanted to say (but forgot) that you can use flatMap to get a None if the mapped value is null:
Given a mapper Function<? super T, ? extends U> mapper, it looks like this:
option.flatMap(t -> Option.of(mapper.apply(t)))
or even simpler:
option.map(mapper).flatMap(Option::of)
Is there a convenience method for
.map(mapper).flatMap(Option::of)
? Such a method would be quite useful to not forget the .flatMap(Option::of).
Let me add that I am a huge fan of your work. It wouldn't be an overstatement that vavr completely changed my (work) life.
@MarkusBarthlen thanks for the kind words.
I鈥榤 afraid, we will reduce the API surface area in the upcoming 1.0 instead of adding convenience methods.
Instead, I鈥榤 still thinking about changing the semantics in order to behave like Java... 馃檭馃馃敟
because the questions will remain forever from Java users. Only Scala users understand the current behavior.
Would the following also be appropriate?
Option.of("Hello World").map(s -> null).filter(Objects::nonNull)...
Instead of:
Option.of("Hello World").map(s -> null).flatMap(Option::of)...
@aaiezza Yes, that works fine and is a better solution!