Блок WebSocket(req) { sri => user =>
в вашем примере это просто вызов метода WebSocket
. Ваш блок эквивалентен:
def site(req: RequestHeader, emit: ClientEmit): Response = {
return WebSocket(req)(
new Function1[Sri, Function1[Option[User], Response]]() {
override def apply(sri: Sri): Function1[Option[User], Response] =
new Function1[Option[User], Response]() {
override def apply(user: Option[User]): Response = ???
}
}
)
}
, вызывающему здесь метод WebSocket sri => user => *do something* and return Response
- это синтаксис c сахара для двух объектов Function1 с созданными на самом деле методами применения. Краткое примечание - это два лямбда-выражения. Просто прочитайте немного больше о выражениях и лямбда-выражениях. Если функция содержит только одно выражение, пышные скобки не требуются, и вы можете написать только один вызов метода WebSocket и передать ему лямбда-выражение как функцию из 1 аргумента, который создает функцию из 1 аргумента, который создает объект Response.
взгляните на WebSocket
метод:
private def WebSocket(req: RequestHeader)(f: Sri => Option[User] => Response): Response =
CSRF.check(req) {
ValidSri(req) { sri => auth(req) flatMap f(sri) }
}
Я написал здесь его расширенную версию:
private def WebSocket(req: RequestHeader)(f: Sri => Option[User] => Response): Response =
CSRF.check(req) {
new Function0[Response] {
ValidSri(req) {
new Function1[Sri, Response]() {
sri: Sri =>
val futureOptionUser: Future[Option[User]] = auth.apply(req)
futureOptionUser.flatMap {
optionUser: Option[User] =>
val fAppliedToSri: Function1[Option[User], Response] = f.apply(sri)
val response: Response = fAppliedToSri.apply(optionUser)
return response
}
}
}
}
}
в flatMap
метод состав функции происходит, и это не аналогично функции 2 аргументов, но в данном случае это эквивалентно. Композиция функций более гибкая, чем функция из двух аргументов, вы можете оценить их не в один и тот же момент. Если вы хотите узнать больше о преобразовании между функцией 2 аргумента и 2 функцией 1 аргумента композиции, прочитайте о Curring .