Есть ли неявный в этом вызове 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,

Другие вопросы по тегам