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?
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
Functionvalue of a type that will allow it to typecheck. So if anAis required and it finds aB, it will look for an implicit value of typeB => Ain scope (it also checks some other places like in theBandAcompanion objects, if they exist). Sincedefs can be “eta-expanded” intoFunctionobjects, animplicit def xyz(arg: B): Awill do as well.So the difference between your methods is that the one marked
implicitwill be inserted for you by the compiler when aDoubleis found but anIntis 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
Actionobject (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 markedimplicitif you want, just like in any othervaldeclaration. Here,requestdoesn’t have to be markedimplicitfor 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 thebindFromRequestmethod on the Form class requires an implicitRequestargument.