2011-11-17 19 views
6

Làm cách nào để tạo một lớp học thực hiện các phép toán so sánh trên bất kỳ loại số nào trong Scala?So sánh với các loại số Scala?

Một cách tiếp cận rõ ràng:

import math.Numeric.Implicits._ 

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

kiếm được tôi đây ...

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

Hmmm ... chúng ta có thể làm toán với các loại số, nhưng chúng ta không thể so sánh chúng?

Vì vậy, chúng ta hãy cũng nói rằng TOrdered[T] ...

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

Đó biên dịch. Nhưng hãy thử sử dụng nó?

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

Và tôi nhận được ...

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

Vì vậy, làm thế nào tôi có thể hoạt động trên một số loại được cả hai yêu cầu và số?

Trả lời

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

Tốt, không nhận thức được loại nhập chung đó ngược lại với nhập địa phương 'numeric.mkXXXOps'. Sẽ sử dụng nó. –

+2

'Số' mở rộng' Thứ tự', do đó yêu cầu một giới hạn ngữ cảnh 'Ordering' là thừa! 'T: Numeric' suffices. –

+0

@Sciss: Bạn nói đúng. Đã chỉnh sửa, cảm ơn. – missingfaktor

4

Bạn phải nhập khẩu mkNumericOps và/hoặc mkOrderingOps:

val num = implicitly[Numeric[T]] 

hoặc

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

thì:

import num.{mkNumericOps,mkOrderingOps} 

Bây giờ bạn có thể so sánh và calc với họ. Có lẽ điều đó khiến bạn cho phần đầu tiên của câu hỏi của bạn.

Bằng cách này: Đã đặt hàng và Numeric làm việc như thế:

class Ops[T: Ordered: Numeric] 
+0

Vâng, đó là hiệu quả! Cảm ơn bạn! Tài liệu này ở đâu? – Tim

+2

Điều đó sẽ là 'T: Đặt hàng: Numeric' (hoặc' T <: Đặt hàng: Numeric' hoặc 'T <% Đặt hàng: Numeric') –

+0

@Tim Tôi đã có vấn đề của bản thân mình và nghĩ rằng có phải là một cách không vụng về gọi 'gt'. Vì vậy, tôi đã có một cái nhìn tại API và có bí ẩn này 'mkOrderingOps' ... Luôn luôn có một cái nhìn gần gũi tại API! –