2011-07-16 2 views
14

Sau đây pseudo-Scala mang lại một "tài liệu tham khảo cyclic bất hợp pháp" lỗi:Tại sao tham chiếu tuần hoàn này với phép chiếu loại bất hợp pháp?

trait GenT[A] 
trait T extends GenT[T#A] { 
    type A 
} 

Câu hỏi: Tại sao điều này bất hợp pháp? Có vấn đề cơ bản với âm thanh hay là giới hạn của hệ thống kiểu Scala? Có một công việc xung quanh?

Mục đích của tôi là tạo một đặc điểm T với thành viên loại A có thể được nâng theo yêu cầu đối với thông số loại thông qua siêu đặc điểm GenT[A]. Một ứng dụng có thể là biểu hiện của những hạn chế, ví dụ

def foo[A, S1 <: GenT[A], S2 <: GenT[A]] ... 

Điều này có thể được sử dụng như thể nó là def foo[S1 <: T, S2 <:T] ... với ràng buộc là S1#A == S2#A.

Nếu kỹ thuật này là có thể, nó cũng có thể giúp cho câu hỏi: How to specialize on a type projection in Scala?

Lưu ý: Tôi có thể sử dụng GenT thay vì T ở khắp mọi nơi, nhưng tôi đang cố gắng để tránh điều đó bởi vì nó sẽ gây ra rất nhiều tham số kiểu để lây lan trên tất cả các mã của tôi "lây nhiễm".

Hai câu hỏi dưới đây dường như tương tự nhưng là về một loại khác nhau của tài liệu tham khảo theo chu kỳ:

Trả lời

16

Trong ví dụ đầu tiên của bạn, bạn có thể phá vỡ chu kỳ bằng cách giới thiệu một phụ trợ nhập inbetween GenT [A] và T,

trait GenT[A] 
trait TAux { type A } 
trait T extends TAux with GenT[TAux#A] 

Nhưng từ ví dụ thúc đẩy của bạn, tôi không nghĩ bạn cần phải đi xuống con đường này. Ràng buộc bạn sau có thể được thể hiện trực tiếp sử dụng một tinh tế,

trait T { type A } 
def foo[A0, S1 <: T { type A = A0 }, S2 <: T { type A = A0 }] ... 

Cũng nhớ rằng bạn có thể bề mặt một loại thành viên như một tham số kiểu thông qua một loại bí danh,

trait T { type A } 
type TParam[A0] = T { type A = A0 } 
def foo[A0, S1 <: TParam[A0], S2 <: TParam[A0]] ... 
+0

vĩ đại thông tin, cảm ơn! Tôi đã thực sự cố gắng để bề mặt các thành viên loại. –