Каррированная функция применяется к нескольким спискам аргументов, а не только к одному. Пример функции без каррирования, которая добавляет два параметра Int
, x
и y
:
scala> def plainOldSum(x: Int, y: Int) = x + y
plainOldSum: (x: Int, y: Int)Int
scala> plainOldSum(1, 2)
res4: Int = 3
Аналогичная функция с каррированием:
scala> def curriedSum(x: Int)(y: Int) = x + y
curriedSum: (x: Int)(y: Int)Int
scala> curriedSum(1)(2)
res5: Int = 3
Что Здесь происходит то, что когда вы вызываете curriedSum
, вы фактически получаете два традиционных вызова функций подряд. Первый вызов функции принимает единственный параметр Int
с именем x
и возвращает значение функции для второй функции. Эта вторая функция принимает параметр Int
y
.
Вот функция с именем first
, которая по духу делает то же самое, что и первый вызов традиционной функции curriedSum
:
scala> def first(x: Int) = (y: Int) => x + y
first: (x: Int)Int => Int
Применение функции first
к 1
- другими словами, вызов функции first
и передача 1
дает функцию second
:
scala> val second = first(1)
second: Int => Int = <function1>
Применение функции second
к 2
дает результат:
scala> second(2)
res6: Int = 3
Эти функции first
и second
являются всего лишь иллюстрацией процесса каррирования. Они не связаны напрямую с функцией curriedSum
. Тем не менее, есть способ получить реальную ссылку на "вторую" функцию curriedSum
. Вы можете использовать нотацию заполнителя для использования curriedSum
в частично применяемом выражении функции, например:
scala> val onePlus = curriedSum(1)_
onePlus: Int => Int = <function1>
Подчеркивание в curriedSum(1)_
является заполнителем для второго параметра list.2
Результатом является ссылка на функцию, которая при вызове добавляет единицу к своему единственному аргументу Int
и возвращает результат:
scala> onePlus(2)
res7: Int = 3
И вот как вы получите функцию, которая добавляет два к своему единственному Int
аргумент:
scala> val twoPlus = curriedSum(2)_
twoPlus: Int => Int = <function1>
scala> twoPlus(2)
res8: Int = 4