为什么 Numeric 的行为与 Ordered 不同? [英] Why does Numeric behave differently than Ordered?
问题描述
Scala 有许多可以用作类型类的特征,例如 scala.math
包中的 Ordered
和 Numeric
.
例如,我可以使用 Ordered
编写一个通用方法,如下所示:
def f[T <% Ordered[T]](a: T, b: T) = if (a
我想用 Numeric
做类似的事情,但这不起作用:
def g[T <% Numeric[T]](a: T, b: T) = a * b
为什么Ordered
和Numeric
之间有明显的差异?
我知道还有其他方法可以做到这一点,以下方法可行(使用上下文绑定):
def g[T : Numeric](a: T, b: T) = 隐式[Numeric[T]].times(a, b)
但这看起来比仅仅使用 *
将两个数字相乘要复杂得多.为什么 Numeric
trait 不包括像 *
这样的方法,而 Ordered
确实包括像 <
这样的方法?>
我知道还有 Ordering
,您可以使用与 Numeric
相同的方式,另请参阅 这个答案:
def f[A : Ordering](a: A, b: A) = 隐式[Ordering[A]].compare(a, b)
Ordered
只是一些简单的 pimped 方法,它们返回 Int
或 Boolean
代码>,所以不需要类型技巧.
Numeric
具有根据所使用的确切子类返回不同类型的方法.因此,虽然 Ordered
只不过是一个标记特征,Numeric
是一个功能齐全的类型类.
要恢复您的运算符,您可以在 lhs 操作数上使用 mkNumericOps
(在 Numeric
中定义).
更新
Miles 说的很对,mkNumericOps
是隐式的,所以只要导入 Numeric 的那个实例就会给你所有的魔法......
Scala has a number of traits that you can use as type classes, for example Ordered
and Numeric
in the package scala.math
.
I can, for example, write a generic method using Ordered
like this:
def f[T <% Ordered[T]](a: T, b: T) = if (a < b) a else b
I wanted to do a similar thing with Numeric
, but this doesn't work:
def g[T <% Numeric[T]](a: T, b: T) = a * b
Why is there an apparent discrepancy between Ordered
and Numeric
?
I know there are other ways to do this, the following will work (uses a context bound):
def g[T : Numeric](a: T, b: T) = implicitly[Numeric[T]].times(a, b)
But that looks more complicated than just being able to use *
to multiply two numbers. Why does the Numeric
trait not include methods like *
, while Ordered
does include methods like <
?
I know there's also Ordering
which you can use in the same way as Numeric
, see also this answer:
def f[A : Ordering](a: A, b: A) = implicitly[Ordering[A]].compare(a, b)
Ordered
is just a few simple pimped methods that return either Int
or Boolean
, so no type-trickery is needed.
Numeric
, on the other hand, has methods that return different types depending on the exact subclass used. So while Ordered
is little more than a marker trait, Numeric
is a fully-featured type class.
To get your operators back, you can use mkNumericOps
(defined in Numeric
) on the lhs operand.
UPDATE
Miles is quite right, mkNumericOps
is implicit, so just importing that instance of Numeric will give you back all the magic...
这篇关于为什么 Numeric 的行为与 Ordered 不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!