I'm working on a functional programming library for Java, and I've hit a frustrating issue. I've got the following functions in my Option<V> class:
/**
 * Returns an Option containing the provided value.
 */
public static <V> Option<V> some(V value)
{...}
/**
 * Returns an Option that contains nothing.
 */
public static <V> Option<V> none()
{...}
/**
 * Decide control flow based on whether this is Some or None,
 * returning the result of the chosen operation.
 *
 * @param some the operation to perform on the contained value if there is one
 * @param none the operation to perform if there is no contained value
 * @return the result of the matched operation
 */
public <T> T matchThen(Function<? super V, ? extends T> some, Supplier<? extends T> none)
{...}
I'm currently implementing a method, orElse, that uses the methods above, and is implemented like so:
/**
 * Returns this if it is a Some, otherwise computes an Option from the given Supplier.
 * @param supp the supplier to compute the other Option
 * @return the first present value or None
 */
public Option<V> orElse(Supplier<? extends Option<? extends V>> supp)
{
    return matchThen(
            Option::some, // if there is a value, wrap it back up and return it
            supp::get     // if there isn't a value, get one from the supplier
    );
}
IDEA reports an error with the use of Option::some in orElse:
Bad return type in method reference: cannot convert
Option<V>to? extends Option<? extends V>
My understanding of wildcard captures was that Option<? extends V> accepts any object of type Option<T> where <T extends V>, which would mean that an Option<V> is definitely an Option<? extends V>. Likewise, I'd expect that a ? extends Option<? extends V> type parameter would accept the same thing (an Option<T> as above or an Option<V>).
So, I have two questions:
- Why is this error occurring? I've come to expect this to be the case where ? extends Type<? extends V>works. Is my expectation being misapplied in this case? I can see how I could be misreading the error, as there's a few types involved, and I'll admit I'm not certain my above analysis is correct.
- Is there a fix to the method signatures that doesn't sacrifice flexibility, or does so minimally? I'd love for users of this library to not have to worry about actually-compatible values and functions raising type errors because of my API.
Note
I'm not asking for an implementation of orElse that avoids this type error; I have a tool for that already, and I don't care too much if my implementation uses minor workarounds. My main concern is that users of this library may face this type of issue when implementing their own solutions, so I want to make these methods as flexible type-wise as I can, which is why I have all these wildcards in the first place.
 
    