title: Stream reduction with wildcard types
body: <p>I'm experimenting with <a href="https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#reduce-T-java.util.function.BinaryOperator-" rel="nofollow"><code>Stream.reduce()</code></a>, and have run into a snag with the type system.  Here's a toy example:</p>
  
  <pre><code>public static Number reduceNum1(List&lt;Number&gt; nums) {
    return nums.stream().reduce(0, (a, b) -&gt; a);
  }
  </code></pre>
  
  <p>This works for any <code>List&lt;Number&gt;</code>, but what if I want to be able to reduce a list that <code>? extends Number</code>?  This doesn't compile:</p>
  
  <pre><code>public static Number reduceNum2(List&lt;? extends Number&gt; nums) {
      return nums.stream().reduce((Number)0, (a, b) -&gt; a);
  }
  </code></pre>
  
  <p>With the error:</p>
  
  <pre><code>ReduceTest.java:72: error: no suitable method found for reduce(Number,(a,b)-&gt;a)
          return nums.stream().reduce((Number)0, (a, b) -&gt; a);
                              ^
      method Stream.reduce(CAP#1,BinaryOperator&lt;CAP#1&gt;) is not applicable
        (argument mismatch; Number cannot be converted to CAP#1)
      method Stream.&lt;U&gt;reduce(U,BiFunction&lt;U,? super CAP#1,U&gt;,BinaryOperator&lt;U&gt;) is not applicable
        (cannot infer type-variable(s) U
          (actual and formal argument lists differ in length))
    where U,T are type-variables:
      U extends Object declared in method &lt;U&gt;reduce(U,BiFunction&lt;U,? super T,U&gt;,BinaryOperator&lt;U&gt;)
      T extends Object declared in interface Stream
    where CAP#1 is a fresh type-variable:
      CAP#1 extends Number from capture of ? extends Number
  Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output
  </code></pre>
  
  <p>I get, conceptually, why this happens.  <code>Stream.reduce()</code> must return something of the same type as the source's elements, and <code>? extends Number</code> isn't the same as <code>Number</code>.  But I'm unsure how to handle this case.  How can I allow collections of a subclass (e.g. <code>List&lt;Integer&gt;</code>) to be reduced (or collected)?</p>
  
  <hr>
  
  <p>If it helps, here's a more practical example that similarly fails to compile:</p>
  
  <pre><code>public static &lt;E&gt; Set&lt;E&gt; reduceSet1(List&lt;? extends Set&lt;E&gt;&gt; sets) {
    return sets.stream().reduce(ImmutableSet.&lt;E&gt;of(), (a, b) -&gt; Sets.union(a, b));
  }
  </code></pre>