Why, in Scala, given:
a = List(1, 2, 3, 4)
def f(x : String) = { x }
does
a.map(_.toString)
work, but
a.map(f(_.toString))
give the error
missing parameter type for expanded function ((x$1) => x$1.toString)
Why, in Scala, given:
a = List(1, 2, 3, 4)
def f(x : String) = { x }
does
a.map(_.toString)
work, but
a.map(f(_.toString))
give the error
missing parameter type for expanded function ((x$1) => x$1.toString)
Well... f()
takes a String as a parameter. The construct _.toString
has type A <: Any => String
. The function f()
expects a type of String
, so the example above does not type check. It seems that Scala is friendly in this case and gives the user another chance. The error message means: "By my type inference algorithms this does not compile. Put the types in and it might, if it's something I can't infer."
You would have to write the anonymous function longhand in this case, i.e. a.map(n => f(n.toString))
. This is not a limitation of type inference, but of the wildcard symbol. Basically, when you write a.map(f(_.toString))
, the _.toString
gets expanded into an anonymous function inside the closest brackets it can find -> otherwise this would lead to enormous ambiguity -> imagine something like f(g(_.toString))
. Does this mean f(g(x => x.toString))
or f(x => g(x.toString))
. Worse ambiguities would arise for multiple nested function calls. The Scala type checker therefore takes the most logical solution, as described above.
Nitpick: the first line of your code should be val a = List(1,2,3,4)
:).
-- Flaviu Cipcigan