Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Usage of _ in scala lambda functions

Tags:

scala

Can anyone please explain me why I can do:

a.mapValues(_.size) 

instead of

a.mapValues(x => x.size) 

but I can't do

a.groupBy(_) 

instead of a

a.groupBy(x => x) 
like image 330
Hugo Sereno Ferreira Avatar asked Oct 06 '11 11:10

Hugo Sereno Ferreira


People also ask

What is ._ in Scala?

Scala allows the use of underscores (denoted as '_') to be used as placeholders for one or more parameters. we can consider the underscore to something that needs to be filled in with a value. However, each parameter must appear only one time within the function literal.

What does this symbol => Do in Scala?

Show activity on this post. => is the "function arrow". It is used both in function type signatures as well as anonymous function terms. () => Unit is a shorthand for Function0[Unit] , which is the type of functions which take no arguments and return nothing useful (like void in other languages).

What are lambda functions in Scala?

An anonymous function—also referred to as a lambda—is a block of code that's passed as an argument to a higher-order function. Wikipedia defines an anonymous function as, “a function definition that is not bound to an identifier.”


2 Answers

When you write a.groupBy(_) the compiler understands it as an anonymous function:

x => a.groupBy(x) 

According to Scala Specifications §6.23, an underscore placeholder in an expression is replaced by a anonymous parameter. So:

  • _ + 1 is expanded to x => x + 1
  • f(_) is expanded to x => f(x)
  • _ is not expanded by itself (the placeholder is not part of any expression).

The expression x => a.groupBy(x) will confuse the compiler because it cannot infer the type of x. If a is some collection of type E elements, then the compiler expects x to be a function of type (E) => K, but type K cannot be inferred...

like image 77
paradigmatic Avatar answered Nov 07 '22 07:11

paradigmatic


It isn't easy to see it here:

a.groupBy(_) 

But it's easier to see it in something like this:

a.mkString("<", _, ">") 

I'm partially applying the method/function. I'm applying it to some parameters (the first and last), and leaving the second parameter unapplied, so I'm getting a new function like this:

x => a.mkString("<", x, ">") 

The first example is just a special case where the sole parameter is partially applied. When you use underscore on an expression, however, it stands for positional parameters in an anonymous function.

a.mapValues(_.size) a.mapValues(x => x.size) 

It is easy to get confused, because they both result in an anonymous function. In fact, there's a third underscore that is used to convert a method into a method value (which is also an anonymous function), such as:

a.groupBy _ 
like image 34
Daniel C. Sobral Avatar answered Nov 07 '22 07:11

Daniel C. Sobral