2011-11-17 23 views
6

¿Cómo se puede crear una clase que haga comparaciones matemáticas y en cualquier tipo numérico en Scala?Comparaciones con los tipos numéricos de Scala?

Un enfoque obvio:

import math.Numeric.Implicits._ 

class Ops[T : Numeric] { 
    def add(a: T, b: T) = a + b 
    def gt(a: T, b: T) = a > b 
} 

me gana esta ...

Ops.scala:7: value > is not a member of type parameter T 

Hmmm ... podemos hacer matemáticas con tipos numéricos, pero no podemos compararlos?

Así que vamos a decir que también es TOrdered[T] ...

class Ops[T <: Ordered[T] : Numeric] { 
    def add(a: T, b: T) = a + b 
    def gt(a: T, b: T) = a > b 
} 

que compila. Pero intenta usarlo?

new Ops[Int].gt(1, 2) 

Y consigo ...

Ops.scala:13: type arguments [Int] do not conform to class Ops's type parameter bounds [T <: Ordered[T]] 

Entonces, ¿cómo puedo operar en algún tipo que se ha dado la orden y numérica?

Respuesta

14
scala> import Ordering.Implicits._ 
import Ordering.Implicits._ 

scala> import Numeric.Implicits._ 
import Numeric.Implicits._ 

scala> class Ops[T : Numeric] { 
    | def add(a: T, b: T) = a + b 
    | def gt(a: T, b: T) = a > b 
    | } 
defined class Ops 

scala> new Ops[Int].gt(12, 34) 
res302: Boolean = false 
+0

Niza, no era consciente de ese tipo de importación global en contraste con la importación local de 'numeric.mkXXXOps'. Lo usaré –

+2

'' Numeric' extiende Ordering', por lo que pide un contexto 'Ordering' límites está redundante! 'T: Numérico' es suficiente. –

+0

@Sciss: Tienes razón. Editado, gracias. – missingfaktor

4

debe importarlos mkNumericOps y/o mkOrderingOps:

val num = implicitly[Numeric[T]] 

o

class Ops[T](implicit num: Numeric[T]) 

a continuación:

import num.{mkNumericOps,mkOrderingOps} 

Ahora usted puede comparar y Calc con ellos. Quizás eso te sirva para la primera parte de tu pregunta.

Por cierto: ordenada y numérico funciona así:

class Ops[T: Ordered: Numeric] 
+0

Sí, eso funciona! ¡Gracias! ¿Dónde estaba esto documentado? – Tim

+2

Eso sería 'T: Ordenar: Numérico' (o' T <: Pedido: Numérico' o 'T <% Ordenado: Numérico') –

+0

@Tim Tuve su problema yo mismo y pensé que tenía que haber una manera no tan torpe llamando a 'gt'. Así que eché un vistazo a la API y estaba este misterioso 'mkOrderingOps' ... ¡Siempre mire de cerca la API! –

Cuestiones relacionadas