Here is a short code:
import scala.language.implicitConversions
implicit def str2int(str:String) = str.toInt
object Container {
def addIt[A](x: A)(implicit str2int: A => Int) = 123 + x
def addIt2(x: String)(implicit str2int: String => Int) = 123 + x
}
println(Container.addIt("123"));
println(Container.addIt2("123"));
Two questions:
Any good resource on this topic would be also greatly appreciated. Thank you.
View means a type A
can be "viewed" as type B
, specified by an implicit function A => B
. So, yes, both implicit arguments in addIt
and addIt2
are views.
addIt2
returns 123123
because it is (unfortunately) possible to call +
on two objects where one of them is a String
. This kicks in before Scala looks at the possibility to apply the str2int
conversion. If you don't want that, you can explicitly apply the view:
def addIt2(x: String)(implicit str2int: String => Int) = 123 + str2int(x)
Or you can hide the any2stringadd conversion:
object Container {
import Predef.{any2stringadd => _}
def addIt2(x: String)(implicit str2int: String => Int) = 123 + x
}
Yes it is an implicit view, but it doesn't indicate any specific part of code. It just says that type A should be 'convertible', preferably implicitly to type Int, e.g. implicit converter should be in scope when this method is called.
Looks like when compiler translates first method it sees 123.+(x:A) and tries to find implicit for type A that '+' will compile.
In the second case, however, it sees 123.+(x:String) and there is such an implicit conversion in the Scala Predef. It is in fact a quirk in the Scala implementation. The implicit declaration is:
final class StringAdd(self: Any) {
def +(other: String) = self.toString + other
}
It was left in scala for convenience of former Java developers that are used to syntax like: 123 + "something"
and expect it to be a string.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With