I want a generic function called \"double\", which behaves like this and could be applied to any type with def +(x:T):T method:
double(\"A\")
&g
This is a perfect example of when to use typeclasses.
+ is just a function. You've given the compiler no information such as
def +(t : T, t : T) : T = ...
And you couldn't, because you don't have any idea what a T is.
Here it would work as follows. You have a type constructor, called Doubles:
trait Doubles[T]{
def double(t : T) : T
}
Now in a companion object, just for convenience, I'm going to rewrite your double function as follows:
object Doubles{
def double[T](t : T)(implicit doubles : Doubles[T]) = doubles.double(t)
}
So this says, I can double a T, as long as there's a Doubles for T in scope, or you explicitly provide me with a Doubles for T. Otherwise, I won't be able to double a T, and you'll get a compiler error.
The following are going to be instances of that typeclass Doubles[T]:
object Implicits{
//Now, you wouldn't want to have to write this for
//every kind of number. Scala already provides you with a numeric
//typeclass. So here's a function that gives a Doubles[N]
//whenever you ask for a Doubles[Numeric[T]], i.e. a Doubles for a
//member of the Numeric typeclass:
implicit def numDoubler[N](implicit num : Numeric[N]) : Doubles[N] = new Doubles[N]{
def double(n : N) : N = num.plus(n,n)
}
implicit object stringDoubler extends Doubles[String]{
def double(t : String) : String = t + t
}
//So something like this is no longer needed:
// implicit object intDoubler extends Doubles[Int]{
// def double(t : Int) : Int = t + t
// }
}