Анонимный синтаксис функций Scala

3 ответа

Это забавная вещь в функциональном программировании, которая называется каррированием . По сути, Моисей Шенфинкель и последний Хаскелл Карри (хотя Шонфинкелинг прозвучит странно ...) пришли к идее, что вызов функции с несколькими аргументами, скажем f (x, y) , аналогичен цепочке вызывает {g (x)} (y) или g (x) (y) , где g - функция, которая производит другую функцию в качестве своего вывода.

В качестве примера возьмем функцию f (x: Int, y: Int) = x + y . Вызов f (2,3) , как и ожидалось, даст 5 . Но что происходит, когда мы каррируем эту функцию - переопределим ее как f (x: Int) (y: Int) и назовем ее как f (2) (3) . Первый звонок, f (2) создает функцию, которая принимает целое число y и добавляет к нему 2 -> поэтому f (2) имеет тип Int => Int и эквивалентен функции g (y) = 2 + y . Второй вызов f (2) (3) вызывает вновь созданную функцию g с аргументом 3 , поэтому вычисляется как 5 , как и ожидалось.

Другой способ увидеть это - выполнить сокращение (функциональные программисты называют это бета-редукцией - это похоже на функциональный способ постепенного перехода по строкам) f (2) (3) (обратите внимание, что следующий синтаксис Scala неверен).

f(2)(3)         // Same as x => {y => x + y}
 | 
{y => 2 + y}(3) // The x in f gets replaced by 2
       |
     2 + 3      // The y gets replaced by 3
       |
       5

Итак, после всего этого разговора, f (x) (y) можно рассматривать как просто следующее лямбда-выражение (x: Int) =>

46
ответ дан 1 December 2019 в 06:16
поделиться

Вы частично применяете функцию ModN. Частичное применение функций - одна из основных особенностей функциональных языков. Дополнительные сведения см. В этих статьях о стиле Currying и Pointfree .

3
ответ дан 1 December 2019 в 06:16
поделиться

В этом примере modN возвращает функцию, которая изменяет конкретное N. Это избавляет вас от необходимости делать следующее:

def mod2(x:Int): Boolean = (x%2) == 0
def mod3(x:Int): Boolean = (x%3) == 0

Две пары скобок ограничивают, где вы можете перестать передавать аргументы методу. Конечно, вы также можете просто использовать заполнитель для достижения того же самого, даже если метод имеет только один список аргументов.

def modN(n: Int, x: Int): Boolean = (x % n) == 0

val nums = List(1, 2, 3, 4, 5)
println(nums.filter(modN(2, _)))
println(nums.filter(modN(3, _)))
2
ответ дан 1 December 2019 в 06:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: