Найти тему

Функции от а до я в Scala

Если Вы хотите стать чуть ближе к функциональному подходу написания кода, но словосочетание "функция высшего порядка" наводит на Вас ужас - то давайте попробуем разобраться, что к чему?

И так, первое, что мы должны запомнить, так это то, что функция в Scala - это не метод, а значение(val а не def, проще говоря). Вы спросите - почему? Если Вы читали статью о обращении, то уже должны понимать, как будет происходить вызов функции в каждом из этих вариантов. Однако я бы сравнил функции не с "выполняющим какое-либо действие методом", а с "трубой, по которой течёт вода". Из этого вопрос - зачем Вам каждый раз новая труба, когда вы захотите влить в неё воду? Давайте посмотрим на простейшую функцию scala:

val x2: Int => Int = x => x * 2

Подчёркиванием выделено аннотация, т.е. именно то, что функция должна делать, а жирным текстом - само тело функции. Эту же функцию можно записать иначе:

val x2 = (x:Int) => x * 2

Как видите, здесь аннотация отсутствует, однако в таком случае необходимо явно указать тип входящего значения! И наикратчайший вариант:

val x2 = 2 * (_:Int)

Здесь используется wildcard (_) - это обозначение свободного параметра, принимающегося функцией, однако от его типизации так же не убежать.

Собственно то, что функции являются значением даёт нам возможность принимать эти значения в функцию(функция, принимающая функцию, похоже на рекурсию, но нет)! Возьмём такой пример - функцию, решающую простой пример из составных:

val des = (a: Int => Int, b: Int => Int) => a.andThen(b)
val
des2 = (a: Int => Int, b: Int => Int) => a.compose(b)

println(des(_*2,_+3)(20))
println(des2(_*2,_+3)(20))

Функция принимает две другие функции, и составляет из двух одну, при вызове этой функции мы должны передать значение входных функций и, затем, значение для обработки!

Вы спросите, почему тут 2 функции, и в их компановке 2 различный метода, compose() и andThen()? Если запустите код, то увидите разницу - она в порядке выполнения. andThen() говорит - после выполнения a выполняй b, compose(), соответственно, действует наоборот.

Таким образом можно комбинировать совершенно различные функции, разница лишь в том, что такой подход более "математичный". Если тема интересно, пишите в комментариях, попробую продемонстрировать больше возможностей на других интересных примерах!