Каррирование
Частичное применение
«Каррирование» — бесплатный урок Scala for Backend Engineering & Functional Programming на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Scala for Backend Engineering & Functional Programming, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Scala for Backend Engineering & Functional Programming содержит 4 уроков всего.
Что такое каррирование?
Каррирование преобразует функцию с несколькими аргументами в цепочку функций, каждая из которых принимает один аргумент. В Scala это записывается с помощью нескольких списков параметров.
object Main {
def add(a: Int)(b: Int): Int = a + b
def main(args: Array[String]): Unit = {
println(add(3)(4))
}
}Несколько списков параметров
Каррированный метод имеет несколько списков параметров: def f(a: Int)(b: Int). Его вызывают, последовательно передавая каждый список: f(1)(2).
object Main {
def combine(prefix: String)(value: Int): String = s"$prefix$value"
def main(args: Array[String]): Unit = {
println(combine("id-")(42))
}
}Частичное применение
Вы можете применить только некоторые списки аргументов и получить функцию, ожидающую остальные. Это называется частичным применением.
object Main {
def add(a: Int)(b: Int): Int = a + b
def main(args: Array[String]): Unit = {
val addFive = add(5) _
println(addFive(10))
println(addFive(20))
}
}Специализация общей функции
Частичное применение позволяет создавать специализированные функции из общей, уменьшая повторение кода.
object Main {
def power(exp: Int)(base: Int): Int = math.pow(base, exp).toInt
def main(args: Array[String]): Unit = {
val square = power(2) _
val cube = power(3) _
println(square(5))
println(cube(2))
}
}Каррирование обычной функции
Обычное значение функции имеет метод .curried, который преобразует его в каррированную форму.
object Main {
def main(args: Array[String]): Unit = {
val add = (a: Int, b: Int) => a + b
val curriedAdd = add.curried
println(curriedAdd(3)(4))
}
}Обратное преобразование из каррированной формы
Вспомогательная функция Function.uncurried выполняет обратное преобразование, превращая каррированную функцию в функцию с одним списком параметров.
object Main {
def main(args: Array[String]): Unit = {
val curried: Int => Int => Int = a => b => a + b
val normal = Function.uncurried(curried)
println(normal(3, 4))
}
}Зачем нужно каррирование
Каррирование позволяет повторно использовать код: один раз зафиксировать первые аргументы, а затем много раз вызывать полученный результат с разными оставшимися аргументами. Кроме того, оно помогает компилятору выводить типы в последующих списках параметров.
object Main {
def discount(rate: Double)(price: Double): Double = price * (1 - rate)
def main(args: Array[String]): Unit = {
val blackFriday = discount(0.3) _
println(blackFriday(100))
println(blackFriday(250))
}
}Вывод типов в последнем списке
Практическая причина использовать несколько списков параметров: компилятор может вывести типы параметров лямбды из предыдущих списков, поэтому их можно не указывать.
object Main {
def fold[A](xs: List[A])(init: A)(op: (A, A) => A): A =
xs.foldLeft(init)(op)
def main(args: Array[String]): Unit = {
val total = fold(List(1, 2, 3))(0)((a, b) => a + b)
println(total)
}
}Каррирование с тремя списками
Можно использовать сколько угодно списков параметров. Каждый вызов передаёт один список и возвращает функцию для следующего.
object Main {
def make(a: Int)(b: Int)(c: Int): Int = a + b + c
def main(args: Array[String]): Unit = {
println(make(1)(2)(3))
val step = make(10) _
println(step(20)(30))
}
}Создание настраиваемых проверок
Распространённый практический пример: каррировать правило проверки, зафиксировать порог и повторно использовать полученный предикат для набора данных.
object Main {
def atLeast(min: Int)(value: Int): Boolean = value >= min
def main(args: Array[String]): Unit = {
val adult = atLeast(18) _
println(List(15, 21, 18, 12).map(adult))
}
}Каррирование и частичное применение
Каррирование — это структурное преобразование в функции с одним аргументом. Частичное применение — это передача одних аргументов сейчас, а остальных позже. Каррированные функции делают частичное применение естественным.
object Main {
def greet(greeting: String)(name: String): String = s"$greeting, $name!"
def main(args: Array[String]): Unit = {
val sayHi = greet("Hi") _
println(sayHi("Ann"))
println(sayHi("Bob"))
}
}Быстрая проверка
Как определить каррированный метод в Scala?
Повторение
Вы изучили каррирование и частичное применение:
- В каррированных методах используются несколько списков параметров:
f(a)(b) - Примените функцию частично с помощью
f(x) _, чтобы получить новую функцию .curriedиFunction.uncurriedпреобразуют функции между формами- Это помогает повторно использовать код, специализировать функции и выводить типы
Часто задаваемые вопросы
Урок «Каррирование» бесплатный?
Да — полный текст урока «Каррирование» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Scala for Backend Engineering & Functional Programming, подпишись на CoddyKit PRO. Курс Scala for Backend Engineering & Functional Programming содержит 4 уроков всего.
Чему я научусь в уроке «Каррирование»?
Частичное применение Ты практикуешь Scala for Backend Engineering & Functional Programming с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Scala for Backend Engineering & Functional Programming?
Предыдущий опыт не требуется. Scala for Backend Engineering & Functional Programming на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Каррирование»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Scala for Backend Engineering & Functional Programming?
Да. Каждый урок Scala for Backend Engineering & Functional Programming включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Функции как значения
- Каррирование
- Композиция
- Замыкания