Scala Code демистифицирует - PullRequest
       13

Scala Code демистифицирует

10 голосов
/ 22 декабря 2011

Может ли кто-нибудь демистифицировать этот код, который является частью примера zentasks в платформе Play20. Мне любопытно, как это работает, при условии, что я новичок в Scala с Java, поэтому многие вещи сложно обернуть.

def IsAuthenticated(f: => String => Request[AnyContent] => Result) = 
  Security.Authenticated(username, onUnauthorized) { user =>
    Action(request => f(user)(request))
  }

Ответы [ 2 ]

16 голосов
/ 22 декабря 2011

Вам нужно немного разделить подпись. f - это функция, которая принимает еще не вычисленную строку => String и возвращает другую функцию , которая принимает Request[AnyContent] и возвращает результат.

Вызов Security.Authenticated принимает два списка параметров. Тот, который имеет username и onUnauthorized. Второй принимает функцию, принимающую пользователя и возвращающую действие.

Метод Action.apply принимает функцию Request[AnyContent] => Result

Итак, f называется «карри». То есть вызывается первая функция, а затем результирующая функция сразу используется f(user)(request).

Вот то же самое, отговоренное (по крайней мере, насколько я могу) и безобразное:

def isAuthenticated(f: => String => Request[AnyContent] => Result) =
  Security.Authenticated(username, onUnauthorized) { user: String =>
     Action.apply { request: Request[AnyContent] =>
       val hiddenTmp: Request[AnyContent] => Result = f(user)
       hiddenTemp.apply(request)
     }
  }

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

2 голосов
/ 22 декабря 2011

Прежде всего, руководство пользователя к моему ответу: я буду использовать курсив , чтобы указать функцию, которая используется без явного имени (см. анонимные функции ).

IsAuthenticated - метод, который принимает в качестве параметра аргумент f.

f - это функция, которая принимает Y в качестве параметра и создает экземпляр Result

Y - это функция, которая принимает Z в качестве параметра и создает экземпляр запроса [AnyContent]

Z - это функция, которая не принимает параметров и возвращает строку

IsAuthenticated вызывает Security.Authenticated, передавая имя пользователя и onUnauthorized (функция для вызова, когда пользователь не авторизован для выполнения запрошенного действия).

Я не совсем уверен, что здесь происходит, сам - я еще не очень хорошо разбираюсь в Scala - но мое предположение в том, что Security.Authenticated - это класс case и следующее эквивалентно его наследованию и добавлению конструктора в Java:

{
  Action(request => f(user)(request))
}

Если большая часть моего предположения верна, то вызывается Action (который является методом в Security.Authenticated), передавая в качестве аргумента A .

A - это функция, которая принимает объект Request (я предполагаю это имя класса) и выдает результат. Использование Результата подразумевается здесь, потому что реализация A является вызовом f.

Таким образом, когда создается экземпляр подкласса Security.Authenticated, вызывается Action, которая аутентифицирует пользователя для какого-либо действия (указанного как строка), а затем, если пользователь аутентифицирован, возвращает f (исходный параметр), который предположительно вызывается по действию (после вышеупомянутой аутентификации). Этот вызов f возвращает Result, который также является функцией. Затем, наконец, результат вызывается с запросом (который был передан A ) в качестве параметра.

...