3

我一直在研究一些编译良好的 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].
4

1 回答 1

5

Numeric是一个类型类,这意味着您不使用Numeric[Double]这种方式的实例,而是Numeric[Double]在范围内有一个隐式指定如何执行数字操作(有关 的相关讨论,Double请参见我的答案Ordering)。

所以你正在寻找一个隐含的Numeric[T],而不是一个T => Numeric[T]. 幸运的是,在 Double 范围内有一个,所以你可以写:

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

或者:

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

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

于 2012-12-02T15:55:16.627 回答