0

In this code :

import java.io.File
def recursiveListFiles(f: File): Array[File] = {
  val these = f.listFiles
  these ++ these.filter(_.isDirectory).flatMap(recursiveListFiles)
}

taken from : How do I list all files in a subdirectory in scala?

Why does flatMap(recursiveListFiles) compile ? as recursiveListFiles accepts a File parameter ? Is file parameter implicitly passed to recursiveListFiles ?

Community
  • 1
  • 1
blue-sky
  • 51,962
  • 152
  • 427
  • 752

3 Answers3

1

No because the expanded flatMap looks like:

flatMap(file => recursiveListFiles(file))

So each file in these is getting mapped to an Array[File], which gets flattened in flatMap. No implicit magic here (in the way that you're asking).

Michael Zajac
  • 55,144
  • 7
  • 113
  • 138
0

flatMap takes a function f: (A) ⇒ GenTraversableOnce[B] to return List[B].

In your case, it is taking recursiveListFiles which is a File ⇒ Array[File] to therefore return a List[File]. This resulting List[File] is then concatenated to these.

Jean Logeart
  • 52,687
  • 11
  • 83
  • 118
0

Sort of. flatMap quite explicitly passes an argument to its own argument. This is the nature of a higher-order function -- you basically give it a callback, it calls the callback, and then it does something with the result. The only implicit thing happening is conversion of a method to a function type.

Any method can be converted to an equivalent function type. So def recursiveListFiles(f: File): Array[File] is equivalent to File => Array[File], which is great, because on an Array[File], you have flatMap[B](f: File => Array[B]): Array[B], and your method's function type fits perfectly: the type parameter B is chosen to be File.

As mentioned in another answer, you could explicitly create that function by doing:

these.filter(_.isDirectory).flatMap(file => recursiveListFiles(file)) or these.filter(_.isDirectory).flatMap(recursiveListFiles(_)) or these.filter(_.isDirectory).flatMap(recursiveListFiles _)

In more complex circumstances, you might need to work with one of those more verbose options, but in your case, no need to bother.

acjay
  • 34,571
  • 6
  • 57
  • 100