title: Why can't the compiler figure out (_ >: T) => (_ <: V[_ <: U]) <: T => V[U] for V[+_]?
body: <p>So I was playing around a bit, trying to write something on existentials and variance, and I came across this interesting piece of code.</p>
  
  <pre><code>final case class Box[+T](val value: T) {
    def &gt;&gt;=[U](f: T =&gt; Box[U]) = f(value)
    def flatMap[U](f: (_ &gt;: T) =&gt; (_ &lt;: Box[_ &lt;: U])): Box[U] = this &gt;&gt;= f
  }
  </code></pre>
  
  <p>This fails to compile:</p>
  
  <pre><code>Variance.scala:3: no type parameters for method &gt;&gt;=: (f: T =&gt; Box[U])Box[U] exist so that it can be applied to arguments (_$1 =&gt; _$2)
   --- because ---
  argument expression's type is not compatible with formal parameter type;
   found   : _$1 =&gt; _$2 where type _$2 &lt;: Box[_ &lt;: U], type _$1 &gt;: T
   required: T =&gt; Box[?U]
    def flatMap[U](f: (_ &gt;: T) =&gt; (_ &lt;: Box[_ &lt;: U])): Box[U] = this &gt;&gt;= f
                                                                     ^
  Variance.scala:3: type mismatch;
   found   : _$1 =&gt; _$2 where type _$2 &lt;: Box[_ &lt;: U], type _$1 &gt;: T
   required: T =&gt; Box[U]
    def flatMap[U](f: (_ &gt;: T) =&gt; (_ &lt;: Box[_ &lt;: U])): Box[U] = this &gt;&gt;= f
                                                                         ^
  </code></pre>
  
  <p>which I find strange, as isn't <code>(_ &gt;: T) =&gt; (_ &lt;: Box[_ &lt;: U])</code> a subtype of <code>T =&gt; Box[U]</code>? Because <code>Function1</code> is contravariant in the first type parameter, this is a subtype of <code>T =&gt; (_ &lt;: Box[_ &lt;: U])</code>. Since <code>Function1</code> is covariant in the result type, this is a subtype of <code>T =&gt; Box[_ &lt;: U]</code>, and since <code>Box</code> is covariant in its parameter, isn't the entire thing a subtype of <code>T =&gt; Box[U]</code>?</p>
  
  <p>Strangely, changing the code to</p>
  
  <pre><code>// This change is not required ;)
  type Box[T] = `What A Category Theorist Calls "The Identity Monad" And What Everyone Else Calls "A Box"`[T]
  final case class `What A Category Theorist Calls "The Identity Monad" And What Everyone Else Calls "A Box"`[+T](val value: T) {
    def &gt;&gt;=[U](f: T =&gt; Box[U]) = f(value)
    def flatMap[U](f: (_ &gt;: T) =&gt; (_ &lt;: Box[_ &lt;: U])): Box[U] = this &gt;&gt;= (f: T =&gt; Box[U])
  }
  </code></pre>
  
  <p>with a type ascription to "hint" the compiler that <code>f: T =&gt; Box[U]</code> makes it compile. Since there's no implicit conversion or variable declaration here shouldn't this have made no difference?</p>
  
  <p>The other way I found of getting this to compile is writing</p>
  
  <pre><code>def flatMap[U](f: (_ &gt;: T) =&gt; (_ &lt;: Box[_ &lt;: U])): Box[U] = this.&gt;&gt;=[U](f)
  </code></pre>
  
  <p>This makes me believe that the issue is less with the compiler having a hard time getting that <code>(_ &gt;: T) =&gt; (_ &lt;: Box[_ &lt;: U]) &lt;: T =&gt; Box[U]</code> and more with it not being able to infer the type parameter of <code>&gt;&gt;=</code>, which seems to be what the error message is alluding to.</p>
  
  <p>(Using Scala 2.12.1 (with sbt, if that changes anything))</p>