Scala - 将Int隐式转换为数字[Int]

时间:2010-10-27 12:14:51

标签: scala scala-2.8 numeric

我创建了一个可以通过任何可以转换为Numeric

的参数化的类
class Complex[T <% Numeric[T]] (val real : T, val imag : T) {
   //... complex number methods ...
}

然后在代码的其他地方尝试:

var myComplex = new Complex(0, 1)

这会引发编译错误,因为(令人惊讶的是)Int和Numeric [Int]之间或者Int和Integral [Int]之间没有隐式转换。

我错过了什么吗?在某处我没有看到隐式转换吗?

在Numeric.scala中定义了一个名为IntIsIntegral的隐式对象。我尝试使用它来创建自己的隐式转换方法:

def implicit intToNumericInt(val i : Int)(implicit n : IntIsIntegral) = n.fromInt(i)

我很惊讶这是必需的,无论如何,它似乎导致无限递归到.fromInt方法。

我确信我遗漏了一些基本的东西(正如你所知,我是Scala的新手),所以我们会欣赏正确方向的一点。

从示例中可以看出,我正在尝试使用可以接受和使用任何数字类型的复数实现。我希望将此贡献给scalala(线性代数)项目。接下来,我想介绍一个Trait,它描述矩阵中元素的责任(主要是+和*运算符),并将复杂数字的改进支持到矩阵操作库中。

2 个答案:

答案 0 :(得分:9)

你错了。正确的用法是这样的:

class Complex[T](val real : T, val imag : T)(implicit num: Numeric[T]) {
   import num._ // make implicit conversions available
   //... complex number methods ...
}

OrderedOrdering之间的差异相同。可以将Ordered[T]实例与T进行比较,而Ordering[T]提供一种比较几个T的方法。

答案 1 :(得分:2)

在Scala 2.8中,它也可以写成

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

}

这种语法无疑是有点密集的,但它可以更加可读:

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

}

声明class C[T: M]( ... ) { val x = implicitly[M[T]]似乎等同于class C[T]( ... )(implicit x: M[T]) { import x._,如前面解决方案的评论中所述。它不仅仅是语法糖,因为编译方式有所不同,例如:在第一种情况下,x是一种方法,在第二种情况下,它是一个字段。