I was making my way through the Scala playframework tutorial and I came across this snippet of code which had me puzzled:
def newTask = Action { implicit request =>
taskForm.bindFromRequest.fold(
errors => BadRequest(views.html.index(Task.all(), errors)),
label => {
Task.create(label)
Redirect(routes.Application.tasks())
}
)
}
So I decided to investigate and came across this post.
I still don't get it.
What is the difference between this:
implicit def double2Int(d : Double) : Int = d.toInt
and
def double2IntNonImplicit(d : Double) : Int = d.toInt
other than the obvious fact they have different method names.
When should I use implicit
and why?
Best Answer
I'll explain the main use cases of implicits below, but for more detail see the relevant chapter of Programming in Scala.
Implicit parameters
The final parameter list on a method can be marked
implicit
, which means the values will be taken from the context in which they are called. If there is no implicit value of the right type in scope, it will not compile. Since the implicit value must resolve to a single value and to avoid clashes, it's a good idea to make the type specific to its purpose, e.g. don't require your methods to find an implicitInt
!example:
Implicit conversions
When the compiler finds an expression of the wrong type for the context, it will look for an implicit
Function
value of a type that will allow it to typecheck. So if anA
is required and it finds aB
, it will look for an implicit value of typeB => A
in scope (it also checks some other places like in theB
andA
companion objects, if they exist). Sincedef
s can be "eta-expanded" intoFunction
objects, animplicit def xyz(arg: B): A
will do as well.So the difference between your methods is that the one marked
implicit
will be inserted for you by the compiler when aDouble
is found but anInt
is required.will work the same as
In the second we've inserted the conversion manually; in the first the compiler did the same automatically. The conversion is required because of the type annotation on the left hand side.
Regarding your first snippet from Play:
Actions are explained on this page from the Play documentation (see also API docs). You are using
on the
Action
object (which is the companion to the trait of the same name).So we need to supply a Function as the argument, which can be written as a literal in the form
In a function literal, the part before the
=>
is a value declaration, and can be markedimplicit
if you want, just like in any otherval
declaration. Here,request
doesn't have to be markedimplicit
for this to type check, but by doing so it will be available as an implicit value for any methods that might need it within the function (and of course, it can be used explicitly as well). In this particular case, this has been done because thebindFromRequest
method on the Form class requires an implicitRequest
argument.