I\'ve created a class that can be parameterised by anything that can be converted to Numeric
class Complex[T <% Numeric[T]] (val real : T, val imag : T) {
You are using it wrong. The correct usage is like this:
class Complex[T](val real : T, val imag : T)(implicit num: Numeric[T]) {
import num._ // make implicit conversions available
//... complex number methods ...
}
It is the same difference as in between Ordered
and Ordering
. An Ordered[T]
instance can be compared to T
, while an Ordering[T]
provides a method that compares a a couple of T
.
In Scala 2.8, it can also be written as
class Complex[T: Numeric] (val real : T, val imag : T) {
def +(that: Complex[T]) = {
val r = implicitly[Numeric[T]].plus(this.real, that.real)
val i = implicitly[Numeric[T]].plus(this.imag, that.imag)
new Complex(r, i)
}
}
This syntax is admittedly a bit dense, but it can be made more readable like this:
class Complex[T: Numeric] (val real : T, val imag : T) {
val num = implicitly[Numeric[T]]
def +(that: Complex[T]) = {
new Complex(num.plus(this.real, that.real), num.plus(this.imag, that.imag))
}
}
The declaration class C[T: M]( ... ) { val x = implicitly[M[T]]
would seem to be equivalent to class C[T]( ... )(implicit x: M[T]) { import x._
as noted in the comments to the previous solution. It's not simply syntactic sugar, because there are differences in how it is compiled, e.g. in the first case x
is a method, and in the second case it's a field.