Функции высокого порядка (high order function) - это функции, которые либо принимают функцию в качестве параметра, либо возвращают функцию, либо и то, и другое.
Тип функции
Для определения функций высокого порядка прежде всего необходимо представлять, что такое тип функции.
Тип функции определяется следующим образом:
Например, возьмем следующее лямбда-выражение:
Это лямбда-выражение принимает в качестве параметра строку и формально ничего не возвращает (точнее возвращаемым типом является Unit)
Поэтому тип этого выражения будет следующий:
Другой пример: лямбда-выражение принимает два числа и возвращает их сумму:
Это выражение будет иметь следующий тип:
Если лямбда-выражение не принимает никаких параметров, то указываются пустые скобки:
К примеру, этому типу будет соответствовать лямбда-выражение {println("hello")}
При определении лямбда-выражения и присвоении его переменной мы можем явным образом у этой переменной указать тип:
Правда, в данном случае тип можно не указывать, так как компилятор может сам вывести тип переменной.
Передача лямбда-выражения в функцию
Для передачи лямбда-выражения в функцию, необходимо определить у функции параметр, тип которого соответствует типу лямбда-выражения:
В данном случае функция action определяет три параметра. Первый два параметра - числа, а третий параметр - некоторая операция, которая производится над этими числами. На момент определения функции можно не знать, что это будет за операция. Это может быть любое лямбда-выражение, которое принимает два объекта типа Int и возвращает также объект типа Int.
В самой функции action вызываем эту операцию, передавая ей два числа, и полученный результат выводим на консоль.
При вызове функции action мы можем передать для ее третьего параметра лямбда-выражение, которое соответствует этому параметру по типу:
Возвращение функции из функции
В более редких случаях может потребоваться возвратить функцию из другой функции. В этом случае для функции в качестве возвращаемого типа устанавливается тип другой функции. А в теле функции возвращается лямбда выражение.
Например:
Здесь функция selectAction принимает один параметр - key, который представляет тип Int.
В качестве возвращаемого типа у функции указан тип (Int, Int) -> Int.
То есть selectAction будет возвращать некую функцию, которая принимает два параметра типа Int и возвращает объект типа Int.
В теле функции selectAction в зависимости от значения параметра key возвращается определенное лямбда-выражение, которое соответствует типу (Int, Int) -> Int
Используем данную функцию:
Здесь переменная action хранит результат функции selectAction.
Так как selectAction возвращает лямбда-выражение, то и переменная action будет хранить определенное лямбда-выражение. Затем через переменную action можно вызвать это лямбда-выражение.
Поскольку лямбда-выражение соответствует типу (Int, Int) -> Int, то при его вызове ему необходимо передать два числа и соответственно мы можем получить его результат и вывести его на консоль.
Стоить запомнить
- Лямбда-выражение можно передать в параметре функции или использовать его в качестве возвращаемого выражения функции. Функция, использующая лямбда-выражения подобным образом, называется функцией высшего порядка.
- Если последний параметр функции является лямбда-выражением, то при вызове функции лямбда-выражение можно вынести за круглые скобки.
- Если функция получает один параметр, который является лямбда-выражением, то при вызове функции скобки можно опустить.
- Псевдоним типа позволяет задать альтернативное имя для существующего типа. Псевдоним типа определяется ключевым словом typealias