2009-03-27 26 views
14

Tôi muốn viết một hàm hoạt động trên mọi loại Scala với tổng số thứ tự (tức là tôi có thể sử dụng '<' trên đó). Cú pháp cho điều đó là gì? Điều tốt nhất tôi đã đi lên với làCú pháp Scala cho một hàm lấy bất kỳ kiểu con nào được đặt hàng [A]?

def lessThan[T <: Ordered[T]](x: T, Y: T) = x < y 

Điều đó không làm việc, tuy nhiên, khi tôi cố gắng sử dụng nó từ REPL:

scala> lessThan(1, 2) 
<console>:8: error: inferred type arguments [Int] do not conform to method lessThan's type parameter bounds [T <: Ordered[T]] 
     lessThan(1, 2) 
    ^

scala> import runtime._ 
import runtime._ 

scala> lessThan(new RichInt(1), new RichInt(2)) 
<console>:8: error: inferred type arguments [scala.runtime.RichInt] do not conform to method lessThan's type parameter bounds [T <: Ordered[T]] 
     lessThan(new RichInt(1), new RichInt(2)) 

Về cơ bản, tôi tin rằng tôi muốn tương đương này Mã Haskell:

lessThan :: (Ord a) => a -> a -> Bool 
lessThan x y = x < y 

Tôi đang sử dụng scala 2.7.3 trên hệ thống Debian.

Tôi đang thiếu gì và ở đâu?

Trả lời

24

Tương đương với các loại lớp của Haskell trong Scala được thực hiện thông qua implicits. Có hai cách để làm những gì bạn muốn

Việc đầu tiên là với quan điểm giới hạn

scala> def lessThan[T <% Ordered[T]](x : T, y : T) = x < y 
lessThan: [T](T,T)(implicit (T) => Ordered[T])Boolean 

scala> lessThan(1,2) 
res0: Boolean = true 

Thứ hai là với một tham số ngầm

scala> def lessThan[T](x : T, y : T)(implicit f : T => Ordered[T]) = x < y  
lessThan: [T](T,T)(implicit (T) => Ordered[T])Boolean 

scala> lessThan(4,3) 
res1: Boolean = false 

Điều thứ nhất là đường cú pháp cho sau này. Sau này cho phép linh hoạt hơn.

+0

Tại sao bạn phải đưa ngầm định một cách rõ ràng làm tham số cho phương thức? Nếu scala-runtime biết làm thế nào để ngầm chuyển đổi T thành Ordered [T] tại sao tôi cần liệt kê một tham số ngầm định? Cảm ơn! – shj

+2

Trước tiên, bạn không thể chuyển đổi bất kỳ T nào thành một đơn đặt hàng [T]. Ví dụ, xác định thứ tự trên (Int => Int). Thứ hai, khi chuyển đổi có thể, thời gian chạy không biết cách chuyển đổi. Thay vào đó, trình biên dịch biết cách chèn một hàm để thực hiện chuyển đổi khi chạy. –

+0

giống như phương pháp đầu tiên không được chấp nhận [SI-7629] (https://issues.scala-lang.org/browse/SI-7629) –

Các vấn đề liên quan