I\'m trying to implement a generic function that wraps a mathematical Java function. For simplicity, we can assume that the Java function (Java 7) takes one parameter and return
You can't cast Double
to Integer
anyway (because it's boxed). Numeric
just allows you to have a set of mathematical operations (by import num._
) on your T - nothing else (you don't need some mediate type for that). A2 works only because println expecting Any
as a result of f(3)
, so T
is automatically inferred to Any
; println(f[Int](3))
will never work, f[Any](3)
will always work.
If you want to implement generic function which operates Doubles (you may need that only if you have operations specific to Double) - you should better return Double. If you can't - you will have to construct the type manually by analizing T:
def f[A](x: A)(implicit num: Numeric[A]): A = {
val result = new java.lang.Double(num.toDouble(x))
(x match {
case x: Double => result
case x: Int => result.toInt
case x: Float => result.toFloat
case x: Long => result.toLong
}).asInstanceOf[A]
}
The reason why you can't just do result.doubleValue.asInstanceOf[A]
here is that A is already boxed. @specialized
annotation doesn't work for asInstanceOf
(type A is still boxed)
UPDATE: actually @specialized
works:
def f[@specialized(Int, Double, Long, Float) A](x: A)(implicit num: Numeric[A]): A = {
val result = new java.lang.Double(num.toDouble(x))
result.doubleValue.asInstanceOf[A]
}
But it doesn't work in Scala REPL - so be careful!
P.S. Manifests are deprecated: use classTag
/typeTag
instead