Scala Код demystify

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

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

Ответ 1

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

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

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

поэтому f вызывается в "curried". Это называется первая функция, а затем полученная функция сразу используется 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)
     }
  }

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

Ответ 2

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

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

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

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

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

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

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

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

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

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

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