2011-11-17 18 views
6

Scala'da herhangi bir sayısal türle karşılaştırıldığında ve karşılaştırmaları yapan bir sınıf nasıl oluşturulur?Scala'nın Sayısal türleri ile karşılaştırmalar?

Bariz yaklaşım:

import math.Numeric.Implicits._ 

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

bana bu kazanır ...

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

Hmmm ... biz sayısal türleri ile matematik yapabilirsiniz, ama biz onları karşılaştırmak olamaz?

Yani ... en de T Ordered[T] olduğunu söylemek derler

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

edelim. Ama kullanmayı dene?

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

Ve olsun ...

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

yüzden de sipariş ve sayısal bazı türüne çalışabilir nasıl?

cevap

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

Nice, bu tür bir global içe aktarmanın, yerel import 'numeric.mkXXXOps' seçeneğinin aksine farkında değildi. Bunu kullanacak. –

+2

'Numeric'' Sipariş’i genişletir, bu nedenle 'Sipariş' bağlam sınırlarını istemek gereksizdir! 'T: Numeric' yeterlidir. –

+0

@Sciss: Haklısınız. Düzenlendi, teşekkürler. – missingfaktor

4

Sen mkNumericOps ve/veya mkOrderingOps ithal etmek zorunda:

val num = implicitly[Numeric[T]] 

veya

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

:

import num.{mkNumericOps,mkOrderingOps} 

Şimdi karşılaştırmak ve onlarla kalk olabilir. Belki de bu sorunun ilk kısmı için size geliyor. Bu arada

: Sıralı ve Sayısal böyle çalışır:

class Ops[T: Ordered: Numeric] 
+0

Evet, çalışıyor! Teşekkür ederim! Bu nerede belgelendi? – Tim

+2

Bu, "T: Sipariş: Sayısal" (veya "T <: Sipariş: Sayısal" veya "T <% Sipariş Verildi: Sayısal") –

+0

@Tim Sorununuzu kendim çektim ve bu kadar sakıncalı olmayan bir yol olduğunu düşündüm gt’yi çağırıyor. Bu yüzden API'ye bir baktım ve bu gizemli 'mkOrderingOps' vardı… Her zaman API'ye yakından bakın! –