The following code doesn't compile:
def f[T](conv: Option[String => T]) {}
f(Some(_.toInt))
with <console>:13: error: missing parameter type for expanded function ((x$1) => x$1.toInt)
Of course, explicit type makes it fine:
scala> f(Some((x: String) => x.toInt))
Why the compiler can't infer String type here? Is there some kind of ambiguity?
In general, is it possible to check and examine manually the generated code from underscore expansion?
The basic problem (I believe) is that when typing Some(_.toInt)
, the compiler needs to infer the type parameter of Some.apply[A](x: A)
, and to do that, it first needs to typecheck the arguments. So _.toInt
is typechecked with A
(considered as an unknown type constant) as expected type. This fails, because anonymous functions are only allowed not to specify parameter types when the expected type is a function type (or starting with Scala 2.12, a Single Abstract Method type). Then the compiler tries again with undefined
as the expected type, and fails for the same reason.
In this case, the expected return type would actually be sufficient to determine the type parameter, and then this would allow to typecheck _.toInt
, but that's not how it is designed to work.
The gory details, if you want them, are in http://scala-lang.org/files/archive/spec/2.11/06-expressions.html, paragraphs 6.6, 6.23, and 6.26.4.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With