tags:

views:

199

answers:

1

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)
+7  A: 

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

Flaviu Cipcigan