Привет еще раз, я все еще пытаюсь изучить концепции функционального программирования и Scala. Довольно сложно изучать новую парадигму программирования и пытаться полностью изменить свое мышление. Вы можете прочитать часть I в здесь.
Итак, это мои заметки и то, что я понимаю об этих концепциях. Надеюсь, вам понравится! :)

Каррирование
Если мы не знаем, сколько аргументов нам нужно в функции, что нам делать? Это вопрос и каррирование ответа.
Каррирование функции — это функция, которая принимает один аргумент и возвращает новую функцию, которая также принимает один аргумент.
def add(x:Int,y:Int):Int = x+y currying version => def addWithCurrying(x:Int) = (y:Int) => x+y
теперь мы можем вызвать эту функцию
without currying: add(3,5) == 8 addWithCurrying(3)(5) == 8 or val curry = addWithCurrying(3) println(curry) // <function1> println(curry(5)) // 8
Обе эти функции возвращают одно и то же значение, но теперь мы можем вызывать эту функцию только с одним параметром. И мы можем сохранить возвращаемое значение.
def addCurry(x:Int)(y:Int) = x+y
Таким же образом мы можем определить функцию каррирования. И если мы хотим позвонить, мы можем просто ввести
val curry = addCurry(3)_ // <function1> The underscore is a placeholder in this case.
ФУНКЦИОНАЛЬНЫЙ ЛИТЕРАЛ
Это альтернативный синтаксис для определения функции.
(a:Int, b:Int) => a*b
Мы можем определить функцию умножения следующим образом.
val multiply = (a:Int, b:Int) => a*b
Литералы функций анонимны,
но мы можем присвоить этой функции значение и использовать его позже.
Это полезно в функциях высокого порядка. Как и в реализации scala, функция fold
def foldLeft[B](z: B)(op: (B, A) => B): B = {
var result = z
this foreach (x => result = op(result, x))
result
}
op здесь является литералом функции, и это пример для функций высокого порядка. Что такое функции высокого порядка?
Давайте разберемся.
ФУНКЦИИ ВЫСШЕГО ПОРЯДКА
Функции высокого порядка принимают другие функции в качестве параметров или возвращают функцию в качестве результата.
Я последовал примеру scala-tour и пытаюсь понять, что происходит!
val salaries = Seq(20000, 70000, 40000)
val doubleSalary = (x: Int) =› x * 2
val newSalaries = salaries.map(doubleSalary) //
В этом примере значение заработной платы представляет собой последовательность.
Двойная зарплата — это функция, которая умножает элемент на 2 (двойная зарплата — это функциональный литерал)
Функция Map принимает другую функцию в качестве параметра и применяет эту функцию к зарплатам => neWSalaries
Функция карты является примером функций высокого порядка.
def urlBuilder(ssl: Boolean, domainName: String): (String, String) => String = {
val schema = if (ssl) "https://" else "http://"
(endpoint: String, query: String) => s"$schema$domainName/$endpoint?$query"
}
val domainName = "www.example.com"
def getURL = urlBuilder(ssl=true, domainName)
val endpoint = "users"
val query = "id=1"
val url = getURL(endpoint, query)
В этом примере urlBuilder принимает два параметра и возвращает еще один (String,String) => String функции.
Это потому, что urlBuilder принимает параметр ssl, чтобы узнать, безопасен ли этот сайт или нет. если это безопасно, URL-адрес начинается с https, иначе http. Также URL-адрес принимает доменное имя. Таким образом, мы можем создать любой URL-адрес, который захотим. например https://medium.com/.
Но в среде так много ссылок. Что, если вы хотите искать меня в среде? (https://medium.com/searchq=%C3%A7a%C4%9F%C4%B1l%20ilhan%20s%C3%B6zer, мы видим конечную точку поиска после .com)
Каждый запрос в среде (или любом веб-сайте) начните с одной и той же части (https://medium.com/), после чего каждый запрос достигнет другой конечной точки.
Благодаря функциям высокого порядка значение getURL возвращает функцию, которую мы может изменить нашу конечную точку или запросить позже. Это отличный случай, чтобы понять, как работают функции высокого порядка.
ЧАСТИЧНО ПРИМЕНЯЕМЫЕ ФУНКЦИИ
Мы можем определить функции с группой из нескольких параметров, как это
def multiply(x:Int,y:Int): Int = x*y multiply(3,12) // 36
В этом нет ничего необычного. Но в слове функционального программирования есть частично прикладные функции, которые мы можем назвать функцией
просто дать некоторые аргументы. Функции сохраняют эти аргументы и возвращают новую функцию, которая ожидает оставшихся аргументов.
We can call multiply function like this way => multiply(2,_,_) or multiply(_,2,_) def multiply(x:Int, y:Int,z:Int): Int = x*y*z val x = multiply(_,0,_) val z = x(2,_) val y = z(1) println(x,z,y) ///(<function2>,<function1>,2)
В приведенном выше примере мы вызвали умножение только с одним аргументом, а остальные аргументы задали позже.
Я думаю, что вывод x и z показывает, сколько функций осталось в значении x.
Когда функции не осталось (или мы передали все аргументы, которые нужны функции), умножение работает и возвращает x*y*z.
Также мы можем использовать частично примененную функцию в примере urlBuilder
val safe= urlBuilder(true,_) val notSafe = urlBuilder(false,_) val domain = "www.medium.com" val anotherDomain = "www.another.com" safe(domain)(endpoint,query) notSafe(anotherDomain)(endpoint,query)
Мы снова передали несколько аргументов, домен первого аргумента завершает функцию urlBuilder, и эта функция возвращает другую функцию, которая принимает 2 параметра.
Спасибо, кто прочитал все мои заметки, надеюсь, вам понравилось! Пожалуйста чувствуйте свободным дать мне любую обратную связь или спросить любой вопрос. До встречи в третьей части :)