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