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
  • 49,326
  • 140
  • 393
  • 691

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
  • 54,331
  • 7
  • 110
  • 133
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
  • 50,693
  • 11
  • 81
  • 116
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
  • 31,546
  • 5
  • 54
  • 98