Scala: generic type restriction

I am very new to Scala.

I want to implement the universal matrix class of the class Matrix [T]. "The only restriction on T should be that T must implement the" + "and" * "mothod / functions. How do I do this?

For example, I want to be able to use both Int, Double, and my own specific types, for example. Complex

I was thinking something along the lines of:

class Matrix[T <: MatrixElement[T]](data: Array[Array[T]]) { def *(that: Matrix) = ..// code that uses "+" and "*" on the elements } abstract class MatrixElement[T] { def +(that: T): T def *(that: T): T } implicit object DoubleMatrixElement extends MatrixElement[Double]{ def +(that: Double): Double = this + that def *(that: Double): Double = this * that } implicit object ComplexMatrixElement extends MatrixElement[Complex]{ def +(that: Complex): Complex = this + that def *(that: Complex): Complex = this * that } 

All types are checked, but I still cannot create an instance of the matrix. Am I missing an implicit constructor? How can i do this? Or am I completely mistaken about my method?

Thanks in advance Troels

+6
generics scala
source share
3 answers

Finally found the answer :-) I think I was not so far in my first attempt. Here it is: (written for scala 2.8)

 trait MatrixElement[T] { def +(that: T): T def *(that: T): T } object MatrixElement { implicit def intToMatrixElement(x : Int) = new MatrixElement[Int] { def +(y : Int) = x + y def *(y : Int) = x * y } implicit def doubleToMatrixElement(x : Double) = new MatrixElement[Double] { def +(y : Double) = x + y def *(y : Double) = x * y } implicit def complexToMatrixElement(x : Complex) = new MatrixElement[Complex] { def +(y : Complex) = x + y def *(y : Complex) = x * y } } class Matrix[T <% MatrixElement[T] : ClassManifest ](d: Array[Array[T]]) { def *(that: Matrix) = ..// code that uses "+" and "*" on the elements } 

Now I can do things like:

 scala> new Matrix(Array(Array(1,0),Array(0,1))) res0: Matrix[Int] = 1 0 0 1 scala> new Matrix(Array(Array(new Complex(0),new Complex(1)),Array(new Complex(1),new Complex(0)))) res9: Matrix[Complex] = (0.0,0.0i) (1.0,0.0i) (1.0,0.0i) (0.0,0.0i) 
+4
source share

You can use Numeric for Scala 2.8 to do this. It is described here. It will replace MatrixElement and its implementation:

 class Matrix[T : Numeric](data: Array[Array[T]]) { def *(that: Matrix[T]) = // } 
+4
source share

Here's what the Numeric solution looks like:

 // ': Numeric[T]' adds an implicit parameter to the constructor, // which allows T to be used in arithmetic expressions. class Matrix[T: Numeric](val data: Array[Array[T]]) { def *(that: Matrix[T]) = { val nt = implicitly[Numeric[T]] import nt._ // This imports an Implicit View to allow operator syntax this.data(0)(0) * that.data(0)(0) // etc } } 
+2
source share

All Articles