Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make code using Value[T : Numeric] more “flexible” like the “unboxed” counterparts?

If I have code like 5 * 5.0 the result gets converted to the most accurate type, Double.

But this doesn't seem to work with code like

case class Value[T : Numeric](value: T) {
    type This = Value[T]
    def +(m: This) = Value[T](implicitly[Numeric[T]].plus(value, m.value))
    ...
}

implicit def numToValue[T : Numeric](v: T) = Value[T](v)

Is there a way to make things like someIntValue + double work, where someIntValue is Value[Int] and double is Double?

PS: Sorry for the far less-than-perfect title. I'm thankful for suggestions for better wording ...

like image 822
soc Avatar asked Oct 03 '11 02:10

soc


1 Answers

You can do this (with a lot of busywork) by creating implicit operators:

abstract class Arith[A,B,C] {
  def +(a: A, b: B): C
  def -(a: A, b: B): C
  def *(a: A, b: B): C
  def /(a: A, b: B): C
}
implicit object ArithIntLong extends Arith[Int,Long,Long] {
  def +(a: Int, b: Long) = a+b
  def -(a: Int, b: Long) = a-b
  def *(a: Int, b: Long) = a*b
  def /(a: Int, b: Long) = a/b
}
...
def f[A,B,C](a: A, b: B)(implicit arith: Arith[A,B,C]) = arith.*(a,b)


scala> f(5,10L)
res46: Long = 50

but you really have to do more than that, since you need a Numeric equivalent for A and B alone, and the asymmetric operations need to be defined both ways. And it's not really practical to specialize given that there are three types involved.

like image 111
Rex Kerr Avatar answered Nov 18 '22 01:11

Rex Kerr