2011-11-17 76 views
6

如何創建一個在數學類型Scala中進行數學運算比較的類?與Scala的數字類型比較?

一個明顯的方法:

import math.Numeric.Implicits._ 

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

榮獲我這...

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

嗯...我們可以做的數學與數字類型,但我們不能對它們進行比較?

所以,讓我們也說TOrdered[T] ...

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

,編譯。但嘗試使用它?

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

我得到...

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

所以,我怎麼能對某些類型的這既是有序和數字操作?

回答

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

不錯,沒有意識到這種全局導入與本地導入'numeric.mkXXXOps'形成鮮明對比。將使用該。 –

+2

'Numeric'擴展了'Ordering',所以要求'Ordering'上下文邊界是多餘的! 「T:數字」就足夠了。 –

+0

@Sciss:你說得對。編輯,謝謝。 – missingfaktor

4

你必須導入mkNumericOps和/或mkOrderingOps

val num = implicitly[Numeric[T]] 

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

則:

import num.{mkNumericOps,mkOrderingOps} 

現在你可以比較並與他們計算。 也許這會幫助你解決問題的第一部分。

順便說一句:有序和數字就像是:

class Ops[T: Ordered: Numeric] 
+0

沒錯,就是工作!謝謝!這是記錄在哪裏? – Tim

+2

這就是'T:排序:數字'(或'T <:排序:數字'或'T <%排序:數字') –

+0

@Tim我自己有你的問題,並認爲必須有一種不那麼笨拙調用'gt'。所以我看了一下API,並且有這個神祕的'mkOrderingOps' ...總是仔細看看API! –