vaer-k
vaer-k

Reputation: 11773

What does an underscore after a scala method call mean?

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?

Upvotes: 4

Views: 877

Answers (2)

slouc
slouc

Reputation: 9698

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.

Upvotes: 9

PilouPili
PilouPili

Reputation: 2699

I don't know if it helps but I prefer this syntax

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

then numberFunc is basically a delegate corresponding to an instance method (instance being numbers) waiting for a parameter. Which later comes to be a lambda expression in the scala documentation example

Upvotes: 2

Related Questions