Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does an underscore after a scala method call mean?

Tags:

scala

The scala documentation has a code example that includes the following line:

val numberFunc = numbers.foldLeft(List[Int]())_

What does the underscore after the method call mean?

like image 373
vaer-k Avatar asked Dec 17 '22 20:12

vaer-k


1 Answers

It's a partially applied function. You only provide the first parameter to foldLeft (the initial value), but you don't provide the second one; you postpone it for later. In the docs you linked they do it in the next line, where they define squares:

val numberFunc = numbers.foldLeft(List[Int]())_
val squares = numberFunc((xs, x) => xs:+ x*x)

See that (xs, x) => xs:+ x*x, that's the missing second parameter which you omitted while defining numberFunc. If you had provided it right away, then numberFunc would not be a function - it would be the computed value.

So basically the whole thing can also be written as a one-liner in the curried form:

val squares = numbers.foldLeft(List[Int]())((xs, x) => xs:+ x*x)

However, if you want to be able to reuse foldLeft over and over again, having the same collection and initial value, but providing a different function every time, then it's very convinient to define a separate numbersFunc (as they did in the docs) and reuse it with different functions, e.g.:

val squares = numberFunc((xs, x) => xs:+ x*x)
val cubes = numberFunc((xs, x) => xs:+ x*x*x)
...

Note that the compiler error message is pretty straightforward in case you forget the underscore:

Error: missing argument list for method foldLeft in trait LinearSeqOptimized Unapplied methods are only converted to functions when a function type is expected. You can make this conversion explicit by writing foldLeft _ or foldLeft(_)(_) instead of foldLeft. val numberFunc = numbers.foldLeft(ListInt)

EDIT: Haha I just realized that they did the exact same thing with cubes in the documentation.

like image 146
slouc Avatar answered Dec 28 '22 23:12

slouc