为什么Numeric的行为与Ordered不同?

Jes*_*per 10 scala typeclass

Scala有一个号码,你可以为类型类使用,如性状Ordered,并Numeric在包装中scala.math.

例如,我可以使用Ordered如下方法编写泛型方法:

def f[T <% Ordered[T]](a: T, b: T) = if (a < b) a else b
Run Code Online (Sandbox Code Playgroud)

我想做类似的事情Numeric,但这不起作用:

def g[T <% Numeric[T]](a: T, b: T) = a * b
Run Code Online (Sandbox Code Playgroud)

为什么Ordered和之间存在明显的差异Numeric

我知道还有其他方法可以做到这一点,以下方法将起作用(使用上下文绑定):

def g[T : Numeric](a: T, b: T) = implicitly[Numeric[T]].times(a, b)
Run Code Online (Sandbox Code Playgroud)

但这看起来比仅仅能够*乘以两个数字更复杂.为什么Numeric特征不包括类似的方法*,而Ordered包括类似的方法<

我知道Ordering你也可以用同样的方式使用Numeric,另见这个答案:

def f[A : Ordering](a: A, b: A) = implicitly[Ordering[A]].compare(a, b)
Run Code Online (Sandbox Code Playgroud)

Mil*_*bin 12

如果从隐式数值[T]导入它们,则符号运算符可用

def g[T : Numeric](a: T, b: T) = {
  val num = implicitly[Numeric[T]]
  import num._
  a * b
}
Run Code Online (Sandbox Code Playgroud)

如果你想只使用一个运算符,这显然有点笨拙,但在非平凡的情况下,导入的开销并不是那么好.

如果没有明确的导入,为什么运营商不可用?默认情况下,默认情况下使隐含可见的常见考虑因素在这里适用,可能更多因为这些运算符被广泛使用.


Kev*_*ght 5

Ordered只是一些简单的拉皮条方法返回Int或者Boolean,所以不需要类型欺骗.

Numeric另一方面,具有根据所使用的确切子类返回不同类型的方法.因此,虽然Ordered只是一个标记特征,但它Numeric是一个功能齐全的类型.

要使操作员返回,可以在lhs操作数上使用mkNumericOps(定义Numeric).

UPDATE

Miles非常正确,mkNumericOps是隐含的,所以只需导入Numeric实例就能让你恢复所有的魔力......


Ben*_*ngs 5

你可以通过这样做来减少Miles的解决方案,只使用1个额外的行:

从添加的隐式转换A : NumericNumeric[A]#Ops

object Ops {
  implicit def numeric[A : Numeric](a: A) = implicitly[Numeric[A]].mkNumericOps(a)
}
Run Code Online (Sandbox Code Playgroud)

然后将其纳入您的方法的范围

def g[T : Numeric](a: T, b: T) = {
  import Ops.numeric
  a * b
}
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅Scala ticket 3538.