2011-10-03 4 views
6

Si tengo un código como 5 * 5.0, el resultado se convierte al tipo más preciso, Double.¿Cómo hacer código usando Value [T: Numeric] más "flexible" como las contrapartidas "unboxed"?

Pero esto no parece funcionar con un código como

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) 

¿Hay una manera de hacer las cosas como someIntValue + double trabajo, donde es someIntValueValue[Int] y double es Double?

PD: Perdón por el título menos que perfecto. Estoy agradecido por las sugerencias para una mejor redacción ...

+1

También hay http://stackoverflow.com/questions/3088979/how-to-set-up-implicit-conversion-to-allow-arithmetic-between-numeric-types que puede ser útil. –

Respuesta

5

Usted puede hacer esto (con una gran cantidad de trabajo no productivo) mediante la creación de operadores implícitos:

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 

pero que realmente tienen que hacer más que eso, ya necesita un equivalente numérico para A y B solo, y las operaciones asimétricas deben definirse en ambos sentidos. Y no es realmente práctico especializarse dado que hay tres tipos involucrados.

+0

Mhhh .... ¿Es este realmente ese problema poco común que no hay una solución mejor? Otro gran problema con esta solución es que realmente no podemos saber (y por lo tanto cubrir) todos los tipos que se ajustan a 'Numérico [T]'. – soc

+1

@soc - Realmente es así de malo. El problema es que 'numérico' no proporciona ninguna forma de decir la precisión relativa de los tres tipos. Usted podría hacer 'Arith' simplemente un convertidor de' A' o 'B' a' C', y luego '' C' ser 'numérico', y hacer todas sus operaciones matemáticas como' C'. Esto reduciría la repetición, pero igual tendría que escribir los convertidores implícitos. –

Cuestiones relacionadas