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 ...
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With