Scala:对泛型类类型的约束

发布于 2024-08-22 03:10:02 字数 819 浏览 4 评论 0原文

我对 Scala 很陌生。

我想实现一个通用矩阵类“class Matrix[T]”。对 T 的唯一约束应该是 T 应该实现“+”和“*”方法/函数。我该怎么做呢?

例如,我希望能够使用 Int、Double 和我自己定义的类型,例如 Complex

我正在考虑这样的事情:

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 
}

一切类型检查,但我仍然无法实例化矩阵。我缺少隐式构造函数吗?我该怎么做呢?或者我的方法完全错误?

提前致谢 特罗尔斯

I am very new to Scala.

I want to implement a generic matrix class "class Matrix[T]". The only constraint on T should be that T should implement a "+" and a "*" mothod/function. How do I go about doing this?

For example I want to be able to use both Int, Double, and my own defined types e.g. Complex

I was thinking something along the lines:

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 
}

Everything type checks but I still can't instantiate a matrix. Am I missing an implicit constructor? How would I go about making that? Or am I completely wrong about my method?

Thanks in advance
Troels

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

您可以使用 Scala 2.8 的 Numeric那。 此处描述 。它将取代 MatrixElement 及其实现:

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

You can use Numeric for Scala 2.8 for that. It is describe here. It would replace MatrixElement and its implementations:

class Matrix[T : Numeric](data: Array[Array[T]]) {
   def *(that: Matrix[T]) = //
}
淡淡の花香 2024-08-29 03:10:02

终于找到了答案:-)我想我的第一次尝试并没有那么遥远。
就这样:(为 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) 

Finally found the answer :-) I think I wasn't that far off in my first try.
Here it goes: (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 stuff 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) 
紫﹏色ふ单纯 2024-08-29 03:10:02

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
   }
}

Here's how the Numeric solution would look:

// ': 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
   }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文