Scala: ограничение на общий тип класса - PullRequest
7 голосов
/ 16 февраля 2010

Я очень новичок в Scala.

Я хочу реализовать универсальный матричный класс "Matrix Class [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 
}

Все проверки типов, но я все еще не могу создать экземпляр матрицы. Я пропускаю неявный конструктор? Как мне сделать это? Или я совершенно не прав в своем методе?

Спасибо заранее Troels

Ответы [ 3 ]

4 голосов
/ 18 февраля 2010

Наконец-то нашел ответ :-) Думаю, я не так уж далек с первой попытки.Вот оно: (написано для 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
}

Теперь я могу делать такие вещи, как:

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 голосов
/ 16 февраля 2010

Для этого вы можете использовать Числовой для Scala 2.8. Это описание здесь . Он заменит MatrixElement и его реализации:

class Matrix[T : Numeric](data: Array[Array[T]]) {
   def *(that: Matrix[T]) = //
}
2 голосов
/ 16 февраля 2010

Вот как будет выглядеть решение 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
   }
}
...