Использовать карринг в Scala одно удовольствие.
Само определение каррирования(или карринга, названо в честь Хаскелла Карри):
Для функции h типа h : (A × B) → C оператор каррирования Λ выполняет преобразование
Λ(h) : A → (B → C)
Отметим, что Λ – это оператор, то есть “функция над функциями”.
Например берем функцию foo(x,y), каррируем и получаем moo(x)(y) – функцию от x которая возвращает функцию от y.
Таким образом мы можем сводим программу к вычислению функции от одного аргумента.
Чтобы выполнить карирование, можно вызвать Function.curried. Сейчас это уже устаревший метод, т.к. curried можно вызывать сразу у функции.
Небольшой пример (для наглядности в императивном стиле):
scala> val foo = (x:Int,y:Int) => x + y // функция от 2(ДВУХ) аргументов x и y. scala> foo(1,2) // просто сложили и получили три scala> val moo = foo.curried // получили функцию от 1(ОДНОГО) аргумента, которая возвращает scala> val zoo = moo(1) // функцию от 1(ОДНОГО) аргумента scala> zoo(2) // урраа! получили три scala> // можно каррировать и так: scala> def noo(x:Int, y:Int) = x * y scala> val a = noo _ // получили функцию от 2-х аргументов (подробнее см. partially applied function) scala> val b = a.curried scala> b(2) // = фунция 2 * аргумент scala> b(2)(3) // = 6
Метод curried можно найти в трейтах начиная от Function2 и заканчивая Function22.
Это значит, что вы можете использовать его для функций от 2 аргументов и до функций с 22-аргументами включительно.
Для функций без аргументов и с одним аргументом использовать бессмысленно.
Для функций с более чем 22-мя не поддерживается (таких трейтов вообще нет).
Например если Вы захотите сделать:
val foo = (x0:Int,x1:Int и т.д. до x22:Int) => 0
то получите ошибку компиляции:
“implementation restricts functions to 22 parameters“.
Чтобы не возникало путаницы, поясню.
- Во-первых:
Это не значит, что вы не можете объявлять методы
def foo(x0:Int,x1:Int и т.д. до x22:Int) = 0
Это будет работать, но использовать в полную “силу” возможности Scala по работе с функциями уже не получится.
Можно считать, что это “обычный” метод с 23 аргументами… - Во-вторых:
Функции с varargs (переменным количество аргументов) работают нормально. Здесь никаких проблем с каррирование быть не должно. -
В-третьих:
Если у вас функции с более чем 22 аргументами это π#_!@#?!!!
Думаете такого не бывает? Когда-то я работал в организации, в которой нужно было писать и разбираться со скриптами на лиспе (было и такое в моей жизни). Так вот, некоторые умельцы декларировали функции от 15-ти и более аргументов.
Я в очередной раз взываю ко всем программистам с планеты Земля.
Пожалуйста, постарайтесь так больше не делать. Уж очень неприятно работать с таким кодом.