Есть ли неявный в этом вызове flatMap?
В этом коде:
import java.io.File
def recursiveListFiles(f: File): Array[File] = {
val these = f.listFiles
these ++ these.filter(_.isDirectory).flatMap(recursiveListFiles)
}
взято из: Как мне перечислить все файлы в подкаталоге в Scala?
Почему flatMap(recursiveListFiles)
компилировать? как recursiveListFiles
принимает File
параметр? Неявно ли передан параметр файла recursiveListFiles
?
3 ответа
Вроде, как бы, что-то вроде. flatMap
вполне явно передает аргумент своему собственному аргументу. Это природа функции более высокого порядка - вы в основном вызываете ее, она вызывает функцию обратного вызова, а затем что-то делает с результатом. Единственное, что происходит неявно, - это преобразование метода в тип функции.
Любой метод может быть преобразован в эквивалентный тип функции. Так def recursiveListFiles(f: File): Array[File]
эквивалентно File => Array[File]
, что здорово, потому что на Array[File]
, у тебя есть flatMap[B](f: File => Array[B]): Array[B]
, и тип функции вашего метода подходит идеально: параметр типа B
выбран, чтобы быть File
,
Как упоминалось в другом ответе, вы можете явно создать эту функцию, выполнив:
these.filter(_.isDirectory).flatMap(file => recursiveListFiles(file))
или жеthese.filter(_.isDirectory).flatMap(recursiveListFiles(_))
или жеthese.filter(_.isDirectory).flatMap(recursiveListFiles _)
В более сложных обстоятельствах вам может понадобиться работать с одним из этих более подробных вариантов, но в вашем случае не нужно беспокоиться.
Нет, потому что расширенный flatMap
похоже:
flatMap(file => recursiveListFiles(file))
Так что каждый file
в these
привязывается к Array[File]
, который сплющивается в flatMap
, Никакой неявной магии здесь (так, как вы просите).
flatMap
берет на себя функцию f: (A) ⇒ GenTraversableOnce[B]
возвращать List[B]
,
В вашем случае это занимает recursiveListFiles
который является File ⇒ Array[File]
поэтому вернуть List[File]
, Это в результате List[File]
затем соединяется с these
,