You want to be able to add instances of your Const
class in the same way that Scala can add different numeric types. But Scala doesn't add different numeric types directly, it uses implicit conversions to first make them the same type. You can do this, too. First, you will need to add Numeric
to your class, as Gábor notes:
case class Const[@specialized(Long, Double) T: Numeric](value: T) {
import Numeric.Implicits._
def +(that: Const[T]) = Const(value + that.value)
}
Then, define the implicit conversion:
implicit def constConvert[A, B: Numeric](a: Const[A])(implicit conv: A => B) =
Const[B](a.value)
This accepts an implicit conversion, and thus generalizes the builtin implicit conversions to your type. Now you can write:
Const(5) + Const(6.0) // Const(11.0)
which compiles to something like:
constConvert(Const(5))(_.toDouble) + Const(6.0)
Since Scala provides sensible implicit conversions for upcasting numeric types, and the constConvert method accepts such an implicit conversion, this will work generally for the builtin numeric types, plus any new types that define sensible conversions and Numerics.
However!
You should be aware that you won't really get the full benefits of specialization here, since the standard library Numeric
is not not specialized (at the time of this writing), so there will still be autoboxing. You may instead want to use a specialized version of Numeric
like the one provided by Spire.