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
родовой.
Имейте в виду, что функциональное программирование - это все о создании функций.