0Pricing
Scala for Backend Engineering & Functional Programming · Урок

Каррирование

Частичное применение

«Каррирование» — бесплатный урок 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 — локальная установка не требуется.

Все уроки этого курса

  1. Функции как значения
  2. Каррирование
  3. Композиция
  4. Замыкания
← Назад к Scala for Backend Engineering & Functional Programming