1

I came from What is the formal difference in Scala between braces and parentheses, and when should they be used? , so still I am not clear understand the scala method call syntax trick. I think the lcn's answer in the link is clear but what does these mean:

val r = List(1, 2, 3).foldLeft(0) _+_ //r: String => String = $Lambda$1642/1200068083@562c1af9
val l = r{"hello"} //l: String = $Lambda$1643/1458648440@23ae6386hello
  1. why r is a function? and call it return another function l and can not call l?

  2. are there some official doc for method call in () and {}?

WesleyHsiung
  • 351
  • 2
  • 13
  • That's a totally misleading way to write it down. At least `.foldLeft(0) _ + _` doesn't suggest that `_` and `_` somehow belong together. The linked answer didn't attempt to generate any optical illusions by removing all spaces in `_+_`. – Andrey Tyukin May 15 '18 at 15:55

1 Answers1

4

This has to do with operator precedence:

val r = List(1, 2, 3).foldLeft(0) _+_ 

Is equivalent to:

val r = (List(1, 2, 3).foldLeft(0) _) + _

Which means - we take the partially applied foldLeft function, List(1, 2, 3).foldLeft(0) _, which has the type ((Int, Int) => Int) => Int), and we call + _ on it.

Now - Scala compiler tries to figure out what the + operator should mean for a Function, and since Function does not define such an operator, it does the best it can to find a suitable implicit conversion, and finds that indeed the Function can be converted to a String using its toString method, so that the + _ means "a new anonymous function that appends any input String passed to the String representation of the List(1, 2, 3).foldLeft(0) _ function".

So we end up with a String => String function, that appends the input to the toString result of the function List(1, 2, 3).foldLeft(0) _, which is "<function1>":

scala> val r = List(1, 2, 3).foldLeft(0) _ + _
r: String => String = <function1>

scala> r("a")
res5: String = <function1>a

scala> r(" bbbb")
res6: String = <function1> bbbb
Tzach Zohar
  • 37,442
  • 3
  • 79
  • 85
  • A small inaccuracy: the implicit conversion is performed not to `String`, but to `scala.runtime.StringAdd`, a class that has only a single method `def +(other: String)` – Kolmar May 15 '18 at 17:02