score:0

Here is a working version (I think the type parameter is required for compatible usage when the two instances parametrized by different types):

  case class Const[@specialized(Long, Double) T: scala.Numeric](value:T){

    def +(that:Const[T]) : Const[T] = {

      //Const(implicitly[Numeric[T]].mkNumericOps(this.value) + that.value)
      import Numeric.Implicits._
      Const(this.value + that.value)

    }

  }

Usage: Const[Double](2) + Const(3.3)

score:0

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.


Related Query

More Query from same tag