2012-05-16 42 views
6

Tôi đang cố gắng tham số hóa một số phương pháp có thông số loại rất chung chung.Loại Scala: giới hạn trên ít nhất

Như một ví dụ, trong REPL tôi lần đầu tiên xác định:

trait Term 
case class FunctionalTerm[+T <: Term](t: T) extends Term 

trực giác, các phương pháp sau đây có một thuật ngữ và một FunctionalTerm, và trả về một cái gì đó với loại ít nhất trên ràng buộc của các loại hạn thông qua và loại đối số của FunctionalTerm:

def ex1[T1 <: Term, T3 <: X, FunctionalTerm[T1] <: X, X <: R, R <: Term](t1: FunctionalTerm[T1], s: T3): R = sys.error("TODO") 

Cho đến nay rất tốt trong REPL.

Sau đó, tôi xác định ex2 như một chức năng tiện lợi mà thực hiện các hoạt động tương tự như ex1, nhưng với các đối số đầu vào hoán đổi:

def ex2[T2 <: Term, T3 <: X, FunctionalTerm[T2] <: X, X <: R, R <: Term](s: T3, t2: FunctionalTerm[T2]): R = ex1(t2,s) 

Cố gắng xác định ex2 trong REPL cung cấp cho các lỗi sau:

error: inferred type arguments [T2,T3,FunctionalTerm,T3,T3] do not conform to method ex1's type parameter bounds [T1 <: Term,T3 <: X,FunctionalTerm[T1] <: X,X <: R,R <: Term] 
     ex1(t2,s) 
     ^
error: type mismatch; 
found : FunctionalTerm[T2] 
required: FunctionalTerm[T1] 
     ex1(t2,s) 
      ^
error: type mismatch; 
found : T3(in method ex2) 
required: T3(in method ex1) 
     ex1(t2,s) 
       ^
error: type mismatch; 
found : R(in method ex1) 
required: R(in method ex2) 
     ex1(t2,s) 
      ^

Tôi đã dành khoảng hai ngày cố gắng tìm ra một giải pháp, và bây giờ hoàn toàn bị mắc kẹt. Tôi không thể tìm thấy bất kỳ thứ gì khác trên Google.

Vì danh sách đối số loại ex2 giống với ex1 nhưng với T1T2 đổi chỗ, tôi không hiểu là sai hoặc cách khắc phục.

Mọi trợ giúp sẽ được đánh giá cao!

Cập nhật

Least cận trên là một cá trích đỏ. Ví dụ có thể được chưng cất thêm.

Hai chức năng sau có thể được định nghĩa trong REPL mà không có lỗi:

def ex1[T1 <: Term, FunctionalTerm[T1] <: Term](t1: FunctionalTerm[T1]): Term = sys.error("TODO: ex1") 
def ex2[T2 <: Term, FunctionalTerm[T2] <: Term](t2: FunctionalTerm[T2]): Term = ex1(t2) 

Giới thiệu các tham số phụ X dường như gây ra vấn đề. Tôi có thể định nghĩa như sau trong REPL:

def ex3[T1 <: Term, FunctionalTerm[T1] <: X, X <: Term](t1: FunctionalTerm[T1]): Term = sys.error("TODO: ex3") 

Nhưng cố gắng để sau đó xác định:

def ex4[T2 <: Term, FunctionalTerm[T2] <: X, X <: Term](t2: FunctionalTerm[T2]): Term = ex3(t2) 

cung cấp cho các lỗi:

error: inferred type arguments [T2,FunctionalTerm,Nothing] do not conform to method ex3's type parameter bounds [T1 <: Term,FunctionalTerm[T1] <: X,X <: Term] 
     def ex4[T2 <: Term, FunctionalTerm[T2] <: X, X <: Term](t2: FunctionalTerm[T2]): Term = ex3(t2) 
                          ^
error: type mismatch; 
found : FunctionalTerm[T2] 
required: FunctionalTerm[T1] 
     def ex4[T2 <: Term, FunctionalTerm[T2] <: X, X <: Term](t2: FunctionalTerm[T2]): Term = ex3(t2) 
                           ^

Vì vậy, tôi đoán câu hỏi trở thành: Tại sao tham số X không được sử dụng trong chữ ký có hiệu ứng này?

+0

Tôi quên nói rằng tôi đang sử dụng Scala 2.10-M3. –

+0

Bạn không sử dụng các loại cao hơn mặc dù :-) –

+0

@oxbow_lakes Oh ... Tôi cũng sửa –

Trả lời

5

Tôi không chắc liệu bạn có đang gặp phải lỗi hay không, nhưng tôi chắc rằng bạn đang làm cho cuộc sống của bạn trở nên khó khăn hơn rất nhiều. Bạn có thể dựa vào hiệp phương sai và thống nhất đất nước để làm tất cả những công việc khó khăn cho bạn,

scala> trait Term 
defined trait Term 

scala> case class FunctionalTerm[+T <: Term](t: T) extends Term 
defined class FunctionalTerm 

scala> def ex1[T <: Term](t1 : FunctionalTerm[T], s : T) : T = s 
ex1: [T <: Term](t1: FunctionalTerm[T], s: T)T 

scala> class A extends Term ; class B extends A ; class C extends A 
defined class A 
defined class B 
defined class C 
scala> ex1(new FunctionalTerm(new B), new C) 
res0: A = [email protected] 

Note loại kết quả suy ra (đó là tương đương với R của ban đầu của bạn định nghĩa phức tạp hơn) ... đó là A đó là LUB của BC.

Bây giờ phiên bản lật là tầm thường và Just Works,

scala> def ex2[T <: Term](s : T, t1 : FunctionalTerm[T]) : T = s 
ex2: [T <: Term](s: T, t1: FunctionalTerm[T])T 

scala> ex2(new C, new FunctionalTerm(new B)) 
res1: A = [email protected] 
+1

Hóa ra hành vi được báo cáo KHÔNG phải là lỗi. Sử dụng FunctionalTerm [T1] <: X và FunctionalTerm [T2] <: X trong ví dụ ban đầu đã khai báo một tham số kiểu phương thức được gọi là "FunctionalTerm" không liên quan đến lớp case có cùng tên. Tôi đánh dấu đây là câu trả lời, tuy nhiên, vì những gì đã được gợi ý đạt được những gì tôi cần làm. –

+0

Vâng duh! ... tuyệt vời mà cả tôi và @oxbow_lakes đều không nhận ra điều đó! –

2

Tôi sẽ đơn giản hóa ví dụ của bạn (Tôi đang sử dụng 2.9.1):

scala> trait Term; case class FunctionalTerm[+T <: Term](t: T) extends Term; 
defined trait Term 
defined class FunctionalTerm 

scala> def ex1[T1 <: Term, T3 <: X, FunctionalTerm[T1] <: X, X <: R, R <: Term](t1: FunctionalTerm[T1], s: T3): R = sys.error("TODO") 
ex1: [T1 <: Term, T3 <: X, FunctionalTerm[T1] <: X, X <: R, R <: Term](t1: FunctionalTerm[T1], s: T3)R 

Bây giờ tuyên bố phương pháp thứ hai:

scala> def ex2[T2 <: Term, T3 <: X, FunctionalTerm[T2] <: X, X <: R, R <: Term](s: T3, t2: FunctionalTerm[T2]): R = ex1(t2, s) 
<console>:11: error: inferred type arguments [T2,T3,FunctionalTerm,T3,T3] do not conform to method ex1's type parameter bounds [T1 <: Term,T3 <: X,FunctionalTerm[T1] <: X,X <: R,R <: Term] 
     def ex2[T2 <: Term, T3 <: X, FunctionalTerm[T2] <: X, X <: R, R <: Term](s: T3, t2: FunctionalTerm[T2]): R = ex1(t2, s) 
                                ^

Các đáng ngờ điều (với tôi) là loại suy ra [T2,T3,FunctionalTerm,T3,T3] - đặc biệt FunctionalTerm. FunctionalTerm là một phương thức khởi tạo loại * -> * nhưng phương thức mong đợi một loại * ở vị trí này.

Tôi có thể nói rằng đây là (có lẽ) là một lỗi và do đó bạn nên gửi nó vào scala-user mailing list (trước khi tăng một vé) - Adriaan MoorsMiles Sabin có nhiều khả năng để có một câu trả lời chi tiết về việc liệu tôi có đúng hay không.

+0

Rất cám ơn - Tôi nghi ngờ đó là lỗi, nhưng kiến ​​thức hạn chế về các loại khiến tôi thận trọng. Tôi sẽ cập nhật khi tôi giải quyết được vấn đề. –

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