On 04/18/2015 01:58 AM, Andreas Lundblad wrote:
On Fri, Apr 17, 2015 at 03:01:29PM -0700, Steven Schlansker wrote:
On Apr 17, 2015, at 2:37 PM, Remi Forax <fo...@univ-mlv.fr> wrote:
As you can see the code is not bad but the code of chain() could be simplified
if there was a way on Optional to call a Supplier of Optional if an Optional is 
empty.
Currently, orElse() takes a value, orElseGet takes a lambda that will return a 
value
and there is no method that takes a lambda and return an Optional
(like flatMap but but with a supplier that will be called if the Optional is 
empty).

If we add the method orElseChain(Supplier<? extends Optional<T>> supplier)
perhaps with a better name ?, then the code of chain is better:

  public default TypeProvider chain(TypeProvider provider) {
    return name -> loadType(name).orElseChain(() -> provider.loadType(name));
  }

Am i the only one to think that this method is missing ?
We actually ran into the exact same problem, and wrote the following helper 
method:

public static <X> Optional<X> unlessOpt(@Nonnull Optional<X> first, 
Supplier<Optional<X>> second) {
     return first.isPresent() ? first : second.get();
}

I don't think it's precisely the same as your solution, but it definitely 
indicates a missing method.
There are similar discussion here:
http://stackoverflow.com/questions/24599996/get-value-from-one-optional-or-another

and here:
http://stackoverflow.com/questions/28818506/java-8-optional-orelse-optional

Thanks Andreas,
the second link provides a clever answer
(which as usually with StackOverflow is not the most voted answer :( ),
return name -> loadType(name).map(Optional::of).orElseGet(() -> provider.loadType(name));

by mapping using Optional::of, it creates an Optional of Optional then orElseGet can be used to unwrap it to either an Optional or if the Optional inside the Optional is empty by calling the supplier.

while this solution works, it creates an Optional of Optional just to workaround the fact that
there is no method orElseChain/orElseOptional.


-- Andreas

cheers,
Rémi


Reply via email to