Scala 2.9中定义的Numeric和Double之间的隐式转换在哪里?

时间:2012-12-02 15:20:47

标签: scala numeric implicit-conversion

我一直在编写一些编译正常的scala代码,但不知怎的,我已经打破了隐含的转换,我无法弄清楚我做错了什么。将它归结为一个非常简单的情况,这段代码不能编译,原因似乎是我没有导入Double和Numeric之间的隐式转换[Double]:

import scala.math.Numeric
import scala.math.Numeric._
import scala.math.Numeric.Implicits._
import Ordering.Implicits._

object ImplicitNumericConversions {
  val v: Numeric[Double] = 3.0
}

我可以通过提供自己的功能轻松解决这个问题:

import scala.math.Numeric

object ImplicitNumericConversions {
  def convertDoubleToNumeric(d: Double)(implicit num: Numeric[Double]): Numeric[Double] = num

  val v: Numeric[Double] = convertDoubleToNumeric(3.0)
}

如果我隐式转换函数,那么我得到了我正在寻找的东西:

import scala.math.Numeric

object ImplicitNumericConversions {

  implicit def convertDoubleToNumeric(d: Double)(implicit num: Numeric[Double]): Numeric[Double] = num

  val v: Numeric[Double] = 3.0
}

...但为什么scala.math.Numeric的导入不能为我做这个?

我正在处理的实际问题如下:

class NumericRange[T <% Numeric[T]](val lower: T, val upper: T) { ... }

object NumericRange {

  def apply[T](lower: T, upper: T)(implicit num: Numeric[T]) = {
    import num._
    new NumericRange[T](lower, upper)
  }
}

...创建新NumericRange的行不会使用这些错误进行编译:

Multiple markers at this line
    - No implicit view available from T => scala.math.Numeric[T].
    - not enough arguments for constructor NumericRange: (implicit evidence$1: T => scala.math.Numeric[T])org.reductio.rtree.NumericRange[T]. Unspecified value parameter 
     evidence$1.
    - not enough arguments for constructor NumericRange: (implicit evidence$1: T => scala.math.Numeric[T])org.reductio.rtree.NumericRange[T]. Unspecified value parameter 
     evidence$1.
    - No implicit view available from T => scala.math.Numeric[T].

1 个答案:

答案 0 :(得分:5)

Numerictype class,这意味着您不能以这种方式使用Numeric[Double]的实例,而是在范围内只有一个隐式Numeric[Double]指定如何对Double执行数字操作(有关Ordering的相关讨论,请参阅my answer here。)

因此,您正在寻找隐式Numeric[T],而不是T => Numeric[T]。幸运的是有one of those in scope for Double,所以你可以写:

class NumericRange[T: Numeric](val lower: T, val upper: T) { ... }

或者:

class NumericRange[T](val lower: T, val upper: T)(implicit
  ev: Numeric[T]
) { ... }

第一个中的“上下文绑定”只是第二个隐式参数的语法糖。