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.