How to define function literal with multiple implicit arguments in Scala? I\'ve tried this way:
def create = authAction { (implicit request, user) ⇒ // Synta
Just had a similar situation as you, implementing an authAction function in Play that would easily pass a user in. You can do it like lambdas did it, with currying; I ended up making my authAction
function receive the RequestHeader
implicitly, but pass in both request and user explicitly:
def authAction(f: (RequestHeader, User) => Result)(implicit request: RequestHeader) = {
...
val authUser = loadUser(...)
f(request, authUser)
}
And to use it:
def create = authAction { (request, user) =>
Ok(html.user.create(registrationForm))
}
As stated in previous answer, you can only define a single implicit parameter for a function literal, but there is workaround.
Instead of multiple implicit arguments you can write function literal as taking multiple argument lists with one argument each. Then it is possible to mark each argument as implicit. Rewriting original snippet:
def create = authAction { implicit request ⇒ implicit user ⇒
Ok(html.user.create(registrationForm))
}
You can call it from authAction
as f(request)(user)
.
implicit
keyword duplication is annoying, but at least it works.
There is no way to define an anonymous function with multiple implicit parameters.
To elaborate on @pagoda_5b's answer and @paradigmatic's comment, section 6.23 of the Scala Language Specification defines anonymous functions like so:
Expr ::= (Bindings | [‘implicit’] id | ‘_’) ‘=>’ Expr
ResultExpr ::= (Bindings | ([‘implicit’] id | ‘_’) ‘:’ CompoundType) ‘=>’ Block
Bindings ::= ‘(’ Binding {‘,’ Binding} ‘)’
Binding ::= (id | ‘_’) [‘:’ Type]
As you can see, you can either define a list of parameters or a single implicit parameter.
If you need multiple parameters to be implicit, you need to curry them.
From what I can understand of the language specification, as of version 2.9.2 you can only define a single implicit parameter for anonymous functions.
E.g.
val autoappend = {implicit text:String => text ++ text}