Scala Language
Функция более высокого порядка
Поиск…
замечания
Scala делает все возможное, чтобы рассматривать методы и функции как синтаксически идентичные. Но под капотом они представляют собой разные понятия.
Метод является исполняемым кодом и не имеет представления значения.
Функция - это фактический экземпляр объекта типа Function1
(или аналогичный тип другой арности). Его код содержится в методе его apply
. Фактически, он просто действует как ценность, которая может быть передана.
Кстати, способность рассматривать функции как ценности - это именно то, что подразумевается под языком, поддерживающим функции более высокого порядка. Экземпляры функций - это подход Scala к реализации этой функции.
Фактическая функция более высокого порядка - это функция, которая либо принимает значение функции в качестве аргумента, либо возвращает значение функции. Но в Scala, поскольку все операции являются методами, более общее представление о методах, которые принимают или возвращают параметры функции. Таким образом, map
, как определено в Seq
может считаться «функцией более высокого порядка» из-за того, что ее параметр является функцией, но это не буквально функция; это метод.
Использование методов в качестве значений функций
Компилятор Scala автоматически преобразует методы в значения функций для передачи их в функции более высокого порядка.
object MyObject {
def mapMethod(input: Int): String = {
int.toString
}
}
Seq(1, 2, 3).map(MyObject.mapMethod) // Seq("1", "2", "3")
В приведенном выше примере MyObject.mapMethod
не является вызовом функции, а вместо этого передается для map
в качестве значения. Действительно, для map
требуется переданное ей значение функции, как видно из ее подписи. Подпись для map
List[A]
(список объектов типа A
):
def map[B](f: (A) ⇒ B): List[B]
Часть f: (A) => B
указывает, что параметр этого вызова метода является некоторой функцией, которая принимает объект типа A
и возвращает объект типа B
A
и B
произвольно определены. Возвращаясь к первому примеру, мы видим, что mapMethod
принимает Int
(что соответствует A
) и возвращает String
(что соответствует B
). Таким образом mapMethod
является допустимым значением функции для перехода к map
. Мы могли бы переписать тот же код, как это:
Seq(1, 2, 3).map(x:Int => int.toString)
Это добавляет значение функции, которое может добавить ясность для простых функций.
Функции высокого порядка (функция как параметр)
Функция более высокого порядка, в отличие от функции первого порядка, может иметь одну из трех форм:
Один или несколько его параметров являются функцией, и она возвращает некоторое значение.
Он возвращает функцию, но ни один из ее параметров не является функцией.
Оба перечисленного: один или несколько его параметров являются функцией, и она возвращает функцию.
object HOF { def main(args: Array[String]) { val list = List(("Srini","E"),("Subash","R"),("Ranjith","RK"),("Vicky","s"),("Sudhar","s")) //HOF val fullNameList= list.map(n => getFullName(n._1, n._2)) } def getFullName(firstName: String, lastName: String): String = firstName + "." + lastName }
Здесь функция map принимает функцию getFullName(n._1,n._2)
в качестве параметра. Это называется HOF (функция высшего порядка).
Аргументы ленивой оценки
Scala поддерживает ленивую оценку аргументов функции с помощью нотации: def func(arg: => String)
. Такой аргумент функции может принимать обычный объект String
или функцию более высокого порядка с типом возвращаемого типа String
. Во втором случае аргумент функции будет оцениваться при доступе к значениям.
См. Пример:
def calculateData: String = {
print("Calculating expensive data! ")
"some expensive data"
}
def dumbMediator(preconditions: Boolean, data: String): Option[String] = {
print("Applying mediator")
preconditions match {
case true => Some(data)
case false => None
}
}
def smartMediator(preconditions: Boolean, data: => String): Option[String] = {
print("Applying mediator")
preconditions match {
case true => Some(data)
case false => None
}
}
smartMediator(preconditions = false, calculateData)
dumbMediator(preconditions = false, calculateData)
вызов smartMediator
возвращает значение None и печатает сообщение "Applying mediator"
.
вызов dumbMediator
возвращает значение None и выводит сообщение "Calculating expensive data! Applying mediator"
.
Ленивая оценка может быть чрезвычайно полезна, когда вы хотите оптимизировать накладные расходы при расчете дорогостоящих аргументов.