What are good reasons for choosing invariance in an API like Stream.reduce()?
<p>Reviewing Java 8 <code>Stream</code> API design, I was surprised by the generic invariance on the <a href="https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#reduce-U-java.util.function.BiFunction-java.util.function.BinaryOperator-" rel="noreferrer"><code>Stream.reduce()</code></a> arguments:</p>

<pre><code>&lt;U&gt; U reduce(U identity,
             BiFunction&lt;U,? super T,U&gt; accumulator,
             BinaryOperator&lt;U&gt; combiner)
</code></pre>

<p>A seemingly more versatile version of the same API might have applied covariance / contravariance on individual references to <code>U</code>, such as:</p>

<pre><code>&lt;U&gt; U reduce(U identity,
             BiFunction&lt;? super U, ? super T, ? extends U&gt; accumulator,
             BiFunction&lt;? super U, ? super U, ? extends U&gt; combiner)
</code></pre>

<p>This would allow for the following, which isn't possible, currently:</p>

<pre><code>// Assuming we want to reuse these tools all over the place:
BiFunction&lt;Number, Number, Double&gt; numberAdder =
    (t, u) -&gt; t.doubleValue() + u.doubleValue();

// This currently doesn't work, but would work with the suggestion
Stream&lt;Number&gt; stream = Stream.of(1, 2L, 3.0);
double sum = stream.reduce(0.0, numberAdder, numberAdder);
</code></pre>

<p>Workaround, use method references to "coerce" the types into the target type:</p>

<pre><code>double sum = stream.reduce(0.0, numberAdder::apply, numberAdder::apply);
</code></pre>

<p>C# doesn't have this particular problem, as <a href="https://msdn.microsoft.com/en-us/library/bb534647(v=vs.110).aspx" rel="noreferrer"><code>Func(T1, T2, TResult)</code></a> is defined as follows, using declaration-site variance, which means that any API using <code>Func</code> gets this behaviour for free:</p>

<pre class="lang-c# prettyprint-override"><code>public delegate TResult Func&lt;in T1, in T2, out TResult&gt;(
    T1 arg1,
    T2 arg2
)
</code></pre>

<p>What are the advantages (and possibly, the reasons for EG decisions) of the existing design over the suggested design?</p>

<p>Or, asked differently, what are the caveats of the suggested design that I might be overlooking (e.g. type inference difficulties, parallelisation constraints, or constraints specific to the reduction operation such as e.g. associativity, anticipation of a future Java's declaration-site variance on <code>BiFunction&lt;in T, in U, out R&gt;</code>, ...)?</p>