Scala Карринг и функциональные литералы

Я читал руководство по неофитам к scala-part-10, где наткнулся на следующий код.

type EmailFilter = Email => Boolean

val minimumSize: Int => EmailFilter = n => email => email.text.size >= n

Я понял первую строку, в которой псевдоним типа EmailFilter создается для функции, которая принимает электронную почту, возвращающую логическое значение. Но я не понимаю вторую строку, где мы берем электронную почту и номер в качестве ввода и возвращаем логическое значение, проверяя размер. Пожалуйста, расшифруйте вторую строку и объясните мне этот синтаксический сахарный код для функции.

2 ответа

Решение

Нет никакого синтаксического сахара вообще, только сырые лямбда-выражения. Если вы подключите type EmailFilter Определив тип во второй строке, вы получите

Int => (Email => Boolean)

что то же самое (из-за правой ассоциативности =>) как

Int => Email => Boolean 

и это идеально соответствует

n   => email => (email.text.size >= n)

который, по сути, просто говорит: дано число n создать фильтр электронной почты, который, учитывая email возвращается true если и только если длина письма не меньше n так, что например

minimumSize(100)

возвращает закрытие, которое ведет себя так же, как

email => email.text.size >= 100

т.е. он фильтрует все электронные письма с длиной больше или равной 100. Таким образом, с соответствующим образом определенным примером почты shortMail а также longMail, вы получите:

minimumSize(100)(shortMail) // false
minimumSize(100)(longMail) // true

minimumSize функция является функцией карри.

Карринг - это способ разбить вызов функции на несколько последовательных вызовов подфункций.

У функции карри есть много хороших преимуществ, одно из которых заключается в том, что она позволяет вашей функции быть более компонуемой, откладывая реальный источник данных.

Давайте изобразим использование:

n => email => email.text.size >= n   

Сначала мы можем вызвать эту функцию, передав параметр для n только:

minimumSize(2) // partially applies the minimumSize function with 2 as n 

Вы получите в это время:

val nextFunction = email => email.text.size >= 2

Следующий звонок nextFunction с электронной почтой:

nextFunction(Email("anemail@domain.com"))

Вы получите в это время логическое значение:

val bool = Email("anemail@domain.com").text.size >= 2

Итак, если мы подведем итоги:

Мы начали с Intзатем Email, затем Boolean:

Int => Email => Boolean

И, посмотрев на эту подпись более внимательно, вы узнаете EmailFilter подпись.
Давайте заменим:

Int => EmailFilter 

Идея состоит в том, чтобы сделать EmailFilter действует как шаблон, который вы можете параметризировать с помощью некоторых более высоких функций.
Здесь мы параметризовали сравнение размера текста электронной почты, чтобы мы могли сохранить EmailFilter родовой.

Имейте в виду, что функциональное программирование - это все о создании функций.

Другие вопросы по тегам