Scala 2.9中定义的数字和双精度之间的隐式转换在哪里 [英] Where are the implicit conversions between Numeric and Double defined in Scala 2.9

查看:69
本文介绍了Scala 2.9中定义的数字和双精度之间的隐式转换在哪里的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在研究一些可编译良好的scala代码,但是以某种方式我破坏了隐式转换,因此我无法弄清自己做错了什么.归结为一个非常简单的情况,此代码无法编译,原因似乎是我没有导入Double和Numeric [Double]之间的隐式转换:

I've been working on some scala code that was compiling fine, but somehow I've broken the implicit conversions and I can't work out what I've done wrong. Boiling it down to a very simple case, this code doesn't compile and the reason seems to be that I'm not importing the implicit conversions between Double and 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
}

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

I can fix this easily enough by providing my own function:

import scala.math.Numeric

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

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

如果我隐含转换函数,那么我得到的是我想要的东西:

If I make the conversion function implicit then I get what I'm looking for:

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导入呢?

... but why don't the imports from scala.math.Numeric do this for me?

我正在研究的实际问题如下:

The actual problem that I'm working on looks like this:

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的行无法通过以下错误进行编译:

... where the line creating the new NumericRange does not compile with these errors:

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].

推荐答案

Numeric类型类,这意味着您不能以这种方式使用Numeric[Double]的实例,而是在范围内只有一个隐式的Numeric[Double],它指定了如何在Double上执行数字运算(请参见在此处我的答案以了解与Ordering相关的讨论.

Numeric is a type class, which means you don't work with instances of Numeric[Double] in this way, but rather that you have a single implicit Numeric[Double] in scope that specifies how to perform numeric operations on Double (see my answer here for a related discussion of Ordering).

因此,您要查找隐式的Numeric[T]而不是T => Numeric[T].幸运的是,有其中一个双击,因此您可以编写:

So you're looking for an implicit Numeric[T], not a T => Numeric[T]. And fortunately there is one of those in scope for Double, so you can just write:

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

或者:

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

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

The "context bound" in the first is just syntactic sugar for the implicit argument in the second.

这篇关于Scala 2.9中定义的数字和双精度之间的隐式转换在哪里的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆