Understanding Scala: Passing Functions as Arguments

I'm starting to learn Scala, and I found a fragment from a tutorial in a Scala tutorial that I don't quite understand. Did anyone want to help me?

This is from Listing 9.1 from programming in Scala, 2nd Edition.

object FileMatcher { private def filesHere = (new java.io.File(".")).listFiles } private def filesMatching(matcher: String => Boolean) = for (file <- filesHere; if matcher(file.getName)) yield file def filesEnding(query: String) = filesMatching(_.endsWith(query)) // ??? def filesContaining(query: String) = filesMatching(_.contains(query)) // ??? def filesRegex(query: String) = filesMatching(_.matches(query)) // ??? 

I am a little confused on lines with // ??? . Does using _ somehow use the anonymous function that is passed to filesMatching ? Or does _ have nothing to do with it, and instead the compiler sees that filesMatching requires a function and therefore does not execute _.endsWith(query) as an expression, but instead makes the expression a function?

+6
source share
3 answers

extended definition

An anonymous function is defined in a more detailed and complete form as

 (a: A, b: B, ...) => function body //using a, b, ... 

eg.

 (a: String, b: String) => a ++ b // concatenates 2 Strings 

inferred types

if the context provides the necessary information (for example, when a higher-order function expects a certain signature for its function arguments), you can omit parameter types, since

 (a, b, ...) => function body //using a, b, ... 

eg.

 val l = List(1, 2, 3) //you can omit the type because filter on List[Int] expects a (Int => Boolean) l.filter(i => i < 3) 

placeholder syntax

Finally, you can use a shorter form if your parameters are used once in each and in the same order that you declare them as the body of the function, as

 _ ++ _ // which is equivalent to (a, b) => a ++ b 

Each _ is a placeholder for function arguments

eg.

filesMatching argument is a function of type String => Boolean , so you can use

 _.endsWith(query) // equivalent to (s: String) => s.endsWith(query) _.contains(query) // equivalent to (s: String) => s.contains(query) _.matches(query) // equivalent to (s: String) => s.matches(query) 
+14
source

Used here _ is a shorthand for a function argument. Thus filesMatching(_.endsWith(query)) equivalent to filesMatching(f => f.endsWith(query)) . Since filesMatching takes String => Boolean as an argument, the compiler can conclude that f is expected to String here. Therefore, you are correct that this expression is an anonymous function.

+3
source

This kind of work is best done by defining the types of functions. I found a great demo here . Combined with this post, the demonstration should clarify recommendations for passing functions as arguments

0
source

All Articles