Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala: application of view

Tags:

scala

view

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:

  1. is "(implicit str2int: A => Int)" called a view? When you say a "view", which specific part of the code does it indicate?
  2. Why does addIt return 246 while addIt2 returns a string "123123"?

Any good resource on this topic would be also greatly appreciated. Thank you.

like image 755
user2125903 Avatar asked Jul 02 '13 07:07

user2125903


2 Answers

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
}
like image 184
0__ Avatar answered Nov 15 '22 08:11

0__


  1. 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.

  2. 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.

like image 26
vitalii Avatar answered Nov 15 '22 08:11

vitalii