Scala/Function literals

From Wikibooks, open books for an open world
Jump to navigation Jump to search

It often occurs that a function is defined only to be used once. Since it is only defined once, it is somewhat superfluous to give it a name. To avoid repeatedly naming and using functions once, there exists a facility to just avoid naming them at all. These are called anonymous functions or function literals. A simple example of a function turned into an anonymous version:

def isEqualToFour(a:Int) = a == 4
(a:Int) => a == 4

The two functions above are effectively the same, except that the second one does not have a name. But the above example is not very exciting. So let's see it in action by applying using it in a higher-order function:

val list = List(1, 2, 3, 4)

list.exists(isEqualToFour)

list.exists((a:Int) => a == 4)

Quite a bit shorter, since we previously had to write "isEqualToFour" twice, and use a "def". But it can be shorter. Since the function literal is used inside a function, the Scala compiler can infer the argument types:

list.exists(a => a == 4)

Much better. But the "a" is basically a throw-away name. When using a function literal inside a higher-order function, instead of defining the arguments, you can just write an expression that uses "_" for the arguments:

list.exists(_ == 4)

This version is about as concise as it gets. The rules for using "_" is that the first-time use of "_" refers to the first argument, the second-time use of "_" refers to the second argument, and so on. So the following example won't work, since the function literal is expected to take just one argument, but the use of "_" twice means that the function literal has two arguments:

list.exists(a => a*a == 4) //Compiles fine.
//list.exists(_*_ == 4) //ERROR: Does not compile!