I tried this way:
def add[A](a:A, b:A): A = {
a + b
}
The compiler says:
Error:(47, 9) type mismatch; found : A required: String a + b
Any one tell me why this error happened? Thank you.
I tried this way:
def add[A](a:A, b:A): A = {
a + b
}
The compiler says:
Error:(47, 9) type mismatch; found : A required: String a + b
Any one tell me why this error happened? Thank you.
Actually Scala doesn't see any common grounds between a Double's + and a an Int's + and also scala keeps this restriction by using Numeric. and its subclasses like Fractional and Integral. You can do your work in different ways like below
def addition[T](x: T, y: T)(implicit num: Numeric[T]): T = {
import num._
x + y
}
or
def add[A](x: A, y: A)(implicit numeric: Numeric[A]): A = numeric.plus(x, y)
Here, you are getting the error because the compiler
cannot infer the actual type of variable a and b
and therefore, it cannot determine
if the +
method is defined for that type A
.
Since you want to add two variables
and not just two numbers,you could pass anonymous function
in the method to define how you want to perform the addition
between those variables. In this way, you could specify, how you want to add two strings
or two integers
or two parameters of any type:
def add[A](a:A,b:A,sum:(A,A)=> A): A = {
sum(a,b)
}
add("john","watson", (a:String,b:String) => a.concat(" "+b))
//result: john watson
add(1,2,(a:Int,b:Int) => a + b)
//result: 3
You can use type classes to achieve this.
First, define a base trait for your operation
trait Addable[T] {
def +(x: T, y: T): T
}
Next, define an default implicits for all the types you wish to be able to add:
implicit object LongAddable extends Addable[Long] {
def +(x:Long, y:Long) = x + y
}
implicit object IntAddable extends Addable[Int] {
def +(x:Int, y:Int) = x + y
}
implicit object StringAddable extends Addable[String] {
def +(x:String, y:String) = s"${x}${y}"
}
Finally, define your method in terms of your type class, using implicit evidence to constrain your parameters:
def add[A](a:A, b:A)(implicit ev: Addable[A]): A = {
ev.+(a,b)
}
Putting all that together allows you to add Ints,Longs, and Strings, all with the same method.
scala> object Example {
| trait Addable[T] {
| def +(x: T, y: T): T
| }
| implicit object LongAddable extends Addable[Long] {
| def +(x:Long, y:Long) = x + y
| }
| implicit object IntAddable extends Addable[Int] {
| def +(x:Int, y:Int) = x + y
| }
| implicit object StringAddable extends Addable[String] {
| def +(x:String, y:String) = s"${x}${y}"
| }
| def add[A](a:A, b:A)(implicit ev: Addable[A]): A = {
| ev.+(a,b)
| }
| }
defined object Example
scala> Example.add(1,2)
res2: Int = 3
scala> Example.add(1L,2)
res3: Long = 3
scala> Example.add("2", "3")
res4: String = 23