0

While experimenting with type variables, I tried following code and it failed (attempted to write a generic code which could add any two data types).

What surprised me was the error. Why does the compiler complain that it expects a String data type? I didn't mention String anywhere in the code

scala> def add[A](x:A, y:A) = {x+y}
<console>:16: error: type mismatch;
 found   : A
 required: String
       def add[A](x:A, y:A) = {x+y
Manu Chadha
  • 15,555
  • 19
  • 91
  • 184

1 Answers1

3

Since A isn't bounded by anything, it could be any type. Specifically, that type doesn't necessarily have a + method (which you try to invoke in the method body). Then, compiler tries to find some implicit conversion that might turn x into some type with a + method, and it finds this implicit conversion into String from Predef.scala:

implicit final class any2stringadd[A](private val self: A) extends AnyVal {
  def +(other: String): String = String.valueOf(self) + other
}

So, the method body becomes equivalent to:

String.valueOf(x).+(y)

But then - compiler fails because String.+ expects a String argument, and y isn't a String.

EDIT: To create a "generic" addition function, you must bound your type A in a way that ensures it can be added. One way of doing that is using the Numeric type:

def add[A : Numeric](x:A, y:A) = { implicitly[Numeric[A]].plus(x, y) }

which means your function can be called for any type A for which an implicit Numeric[A] exists.

Tzach Zohar
  • 37,442
  • 3
  • 79
  • 85