Implicit parameter for literal function

While reading Play! Framework documentation, I came across this snippet:

def index = Action { implicit request => session.get("connected").map { user => Ok("Hello " + user) }.getOrElse { Unauthorized("Oops, you are not connected") } } 

The documentationation explains implicit there:

Alternatively, you can get the session implicitly from the request

Also, I read this post: Literal with Implicit and it seems logical that a function cannot have an implicit parameter.

If I understand well, this is because a function , contrary to the method, always has a contract (interface).

In fact, for example, Function1[Int, Function1[Int, Int]] has the first parameter an Int as the return type, and thus allows us to annotate this text as implicit . This will lead to confusion regarding the high level return type: () => Int or Int => Int ...

Consequently, what the previous code of the fragment leads is implicit, since the first Action required parameter is a literal function.

I assume that the reason the compiler accepts this code is because of the multiple signatures of the Action.apply() method:

  • def apply(block: Request[AnyContent] => Result): Action[AnyContent]
  • def apply(block: => Result): Action[AnyContent] (redirect to first)

Since the second one does not need any parameter, is this one chosen in the presence of an implicit parameter of a literal function?

+4
source share
1 answer

Consider the following code:

 class MyImplicitClass(val session: Int) object Tester { def apply(fun: MyImplicitClass => Int): Int = ??? def apply(fun: => Int): Int = ??? } Tester { implicit myImplicitClass => session * 20} 

If this function:

 def session(implicit myImplicitClass: MyImplicitClass): Int = myImplicitClass.session 

is in scope, then the first code fragment will be compiled, because the explicitly implicit parameter myImplicitClass will be passed to the session function to access the myImplicitClass.session field, which allows you to omit access to the field. This is definitely a trick on the Play! Framework uses Controller to find the session function.

As a side note, the above closure does not indicate that it accepts an implicit parameter, it is a feature of the language to avoid having to do the following:

 Tester { myImplicitClass => implicit val x = myImplicitClass session * 20 } 

when you want to use the closure parameter as an implicit value in the body of the closure. Also note that with Scala 2.9 you are limited to closing with exactly one parameter for this trick.

+6
source

All Articles