Java interop - type inference failure with wildcard types

303 views Asked by At

Is there any way to make this compile (without explicitly writing types)?

import java.util.{function => juf}

def jfun[A,B](f: A => B): juf.Function[A,B] =
  new juf.Function[A,B] { def apply(a: A): B = f(a) }

val l = new java.util.ArrayList[String]
l.stream.map(jfun(_.toInt))

Result:

error: no type parameters for method map: (x$1: java.util.function.Function[_ >: String, _ <: R])java.util.stream.Stream[R] exist so that it can be applied to arguments (java.util.function.Function[String,Int])
 --- because ---
argument expression's type is not compatible with formal parameter type;
 found   : java.util.function.Function[String,Int]
 required: java.util.function.Function[_ >: String, _ <: ?0R]
Note: String <: Any, but Java-defined trait Function is invariant in type T.
You may wish to investigate a wildcard type such as `_ <: Any`. (SLS 3.2.10)
                  l.stream.map(jfun(_.toInt))
                           ^
<console>:18: error: type mismatch;
 found   : java.util.function.Function[String,Int]
 required: java.util.function.Function[_ >: String, _ <: R]
                  l.stream.map(jfun(_.toInt))
                                   ^

Is there any better explanation to why this doesn't work than "scala simply can't do it"?

PS. I know about workarounds like adding extension map method on Stream - I nevertheless would like to hear some explanation for this type inference limitation.

0

There are 0 answers