How does one declare in Scala the type signatures needed to implement multiple arithmetic systems that all share a same trait declaring the operations? I thought I had it solved until I tried to add some helper implementations to the base trait/class. In the following code-snippet (which compiles) notice that sq() is defined as this*self not the more obvious this*this. And self() can not be implemented in the trait either (we have to wait until we get to a concrete extending class to implement it).
trait NumberBase [NUMBERTYPE <: NumberBase[NUMBERTYPE]] {
// type NUMBERTYPE >: this.type
def *(that: NUMBERTYPE):NUMBERTYPE
def self:NUMBERTYPE
def sq:NUMBERTYPE = { this*self }
}
class D(val v:Double) extends NumberBase[D] {
def self:D = { this }
def *(that: D):D = { new D(this.v*that.v) }
}
The question/goal is: remove the use of self() or (at least move self()'s implementation into NumberBase) without changing the type signature of * in D. A lot of the fixes in the above link make the derived class unimplementable (things like new D() not being a type returnable by * or * having an unguessable type signature in D). I don't mind some of the signatures getting uglier- but I would like the code to express what this code expresses: that the derived classes work on their own types only and return instances of their own type (they are not moving up and down in a hierarchy).
I found some discussion here that lists some problems (but don't see a solution): http://www.scala-lang.org/node/839 . Some issues you don't run into until you see both the base class and the implementation.
Complete code with the work-around given above (forcing implementing classes to implement self()) is given here: https://github.com/WinVector/AutoDiff where we use the fact different arithmetic systems share the same base-class or trait to write functions that are generic over different arithmetic implementations. This lets us use a wrapping of standard machine arithmetic (like D) or something else (like a number system that computes gradients as a side-effect).