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)