2011-11-17 58 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! –