If you want to sum some integers in a List, you just call the sum method. So far, so obvious. But if the list does not hold elements that are summable, how does Scala give you a method that you may or may not call?
The sum method lives in TraversableOnce and the signature looks like this:
def sum[B >: A](implicit num: Numeric[B]): B = ...
Here [B >: A] says B must be a superclass of A, the type of elements in the list. The implicit says there must exist in the ether something that provides the functionality in trait Numeric for type B (the functionality for plus, minus etc).
Now, for Int, Double etc you get these for free in the Numeric object that's standard to Scala where you see, for example:
trait IntIsIntegral extends Integral[Int] { ...
which is pulled into the implicit ether with:
implicit object IntIsIntegral extends IntIsIntegral with Ordering.IntOrdering
in the same file. Note, that unlike Java, Scala's numerics do not extend a common superclass like java.lang.Number.
So, we could happily create our own arithmetic with something like:
class MyInteger
trait MyIntegerOrdering extends Ordering[MyInteger] {
def compare(x: MyInteger, y: MyInteger) = ???
}
trait MyIntegral extends Numeric[MyInteger] { // or Integral that extends Numeric[T]
def plus(x: MyInteger, y: MyInteger): MyInteger = new MyInteger
.
.
.
}
implicit object MyIntegerIsIntegral extends MyIntegral with MyIntegerOrdering
It's not a terribly useful arithmetic but it would allow us to have a list of MyIntegers and call sum on it.
No comments:
Post a Comment