1

Given

new Scanner(is)
    .tokens()
    .map(_.toInt)
    .toArray[Int]((_: Int) => Array.ofDim[Int](100000))

I get a compile error

Error:(40, 12) 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, _ <: ?R]
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)
          .map(_.toInt)
Error:(40, 18) type mismatch;
 found   : java.util.function.Function[String,Int]
 required: java.util.function.Function[_ >: String, _ <: R]
          .map(_.toInt)

What is wrong here?

Abhijit Sarkar
  • 21,927
  • 20
  • 110
  • 219
  • 2
    Try `mapToInt` instead of `map`: while Scala tries to treat `Int` etc. as if they were normal classes, it has some problems when interoperating with Java. – Alexey Romanov Nov 09 '18 at 08:28
  • `mapToInt(_.toInt).toArray` does work. Would you care to offer any explanations about the errors, it seems interesting. – Abhijit Sarkar Nov 09 '18 at 08:32

1 Answers1

1

The compiler is trying to find the R type parameter for Stream#map. Because the argument of map is a Function[String,Int], and it must be compatible with Function[_ >: String, _ <: R] (from the signature of map), there is a constraint Int <: R. But because it's a Java method, there's also a constraint R <: Object (at least I think that's what happens). So there's no suitable R.

The error message is not very good in this case, because it doesn't give the second constraint.

To fix, as I mentioned in the comment, you can just use mapToInt, but actually there's an even worse error message which definitely should be fixed (I reported an issue): specifying map[Int] results in

type mismatch;
 found   : Array[Int]
 required: Array[Int]
Note: Int >: Int, but class Array is invariant in type T.
You may wish to investigate a wildcard type such as `_ >: Int`. (SLS 3.2.10)
Abhijit Sarkar
  • 21,927
  • 20
  • 110
  • 219
Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487
  • Your last error is what I started with, if I didn’t have the `map`. Please include the link to the issue you reported, and I’ll be happy to accept your answer. Thank you. – Abhijit Sarkar Nov 09 '18 at 17:31
  • https://github.com/scala/bug/issues/11248 (and there are useful comments there). Note that the bug is just that the error message should be improved, not that the code should work. – Alexey Romanov Nov 09 '18 at 17:47