2011-11-17 13 views
6

W jaki sposób można utworzyć klasę, która analizuje matematykę i na dowolnym typie liczbowym w Scali?Porównania z typami numerycznymi Scali?

Oczywistym podejście:

import math.Numeric.Implicits._ 

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

mi zarabia to ...

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

Hmmm ... możemy zrobić matematyki z typów liczbowych, ale nie można ich porównać?

Warto więc również powiedzieć, że T jest Ordered[T] ...

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

To kompiluje. Ale spróbuj go użyć?

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

I dostać ...

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

Więc jak mogę działać na jakiś rodzaj, który jest zarówno uporządkowany i numerycznej?

Odpowiedz

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

Miło, nie był świadomy tego rodzaju globalnego importu w przeciwieństwie do lokalnego importu 'numeric.mkXXXOps'. Użyje tego. –

+2

'Numeric' rozszerza' Ordering', więc prośba o ograniczenie kontekstu 'Ordering' jest zbędna! "T: numeryczne" wystarcza. –

+0

@Siss: Masz rację. Edytowane, dzięki. – missingfaktor

4

Trzeba importować mkNumericOps i/lub mkOrderingOps:

val num = implicitly[Numeric[T]] 

lub

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

następnie:

import num.{mkNumericOps,mkOrderingOps} 

Teraz można porównać i obliczono z nich. Może to ci pomoże w pierwszej części twojego pytania.

Przy okazji: uporządkowane i numeryczna działa tak:

class Ops[T: Ordered: Numeric] 
+0

Tak, to działa! Dziękuję Ci! Gdzie było to udokumentowane? – Tim

+2

To byłoby 'T: Kolejność: Numeryczna' (lub' T <: Zamówione: Numeryczne' lub 'T <% Zlecone: Numeryczne') –

+0

@Tim Miałem twój problem sam i myślałem, że musi być sposób, że nie tak niezdarny Wywołanie 'gt'. Więc rzuciłem okiem na API i istniało tajemnicze 'mkOrderingOps' ... Zawsze uważnie patrz na API! –

Powiązane problemy