Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala missing parameter type for expanded function

Tags:

scala

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?

like image 346
ars Avatar asked Jul 27 '16 10:07

ars


1 Answers

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.

like image 145
Alexey Romanov Avatar answered Sep 29 '22 15:09

Alexey Romanov