2010-02-16 98 views
6

我对Scala很新。Scala:通用类类型的约束

我想实现一个通用的矩阵类“类矩阵[T]”。 T的唯一约束应该是T应该实现一个“+”和一个“*”方法/函数。我如何去做这件事?

例如,我希望能够同时使用Int,Double和我自己定义的类型,例如复杂

我在想沿着线的东西:

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 
} 

一切类型检查,但我还是不能实例化一个矩阵。我是否缺少隐式构造函数?我将如何去做这件事?或者我完全错了我的方法?

在此先感谢 特勒尔斯

回答

4

终于找到了答案:-)我想我是不是已经不远了,我第一次尝试。 这里有云:(斯卡拉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 
} 

现在我可以做的东西,如:

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

可以使用Numeric斯卡拉2.8这一点。它被描述为here。这将取代MatrixElement及其实现方式:

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

我认为数字。但我真的不知道这对我自己的类型会起什么作用,例如复杂。 我认为复杂然后将需要扩展数字。首先,我需要实现更多的方法,而不仅仅是+和*。在这些排序中 - 据我所知,复数没有严格的排序。 关键在于我需要Matrix来处理任何只填充了方法+和*的类型。 – 2010-02-16 15:20:39

+0

如果你只需要+和*,有很多方法可以实现。但是你仍然可以用这两种方法创建类似Numeric的东西。这应该是两件很多工作。 (也许以后回来,并用数字,如果值得的更换。) – 2010-02-16 15:54:08

+1

@troels您可以通过实部,或只是简单的返回“0”为所有的比较顺序。你总是可以用'error(“Undefined method”)“实现”方法。不过请注意,复杂''不会_extend_'数字'。相反,会有一个'Numeric [Complex]'的实例。 – 2010-02-16 16:20:56

2

这里是如何的Numeric解决办法看:

// ': 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 
    } 
} 
+0

'T:数字[T]'应'T:Numeric'。你没有REPL写这个吗? :-) – 2010-02-16 14:50:42

+0

哎呀!把我抓出来:) – retronym 2010-02-16 15:00:05