2012-01-02 12 views
6

Tôi muốn thư giãn các ràng buộc về tham số kiểu của đặc điểm và thay vào đó áp đặt chúng trên phương thức dưới dạng tham số bằng chứng. Với một số thiết lập xương:Trao đổi giới hạn trên của thông số loại cho một tham số bằng chứng

trait State[Repr] 
object Observer { 
    def apply[Repr <: State[Repr]](reader: Reader[Repr]): Observer[Repr] = 
    new Observer[Repr] {} 
} 
trait Observer[A] 
trait Reader [A] 

này hoạt động:

trait StateX[Repr <: StateX[Repr]] extends State[Repr] { 
    protected def reader: Reader[Repr] 
    def observe: Observer[Repr] = Observer(reader) 
} 

Và đây không:

trait StateY[Repr] extends State[Repr] { 
    protected def reader: Reader[Repr] 
    def observe(implicit ev: Repr <:< State[Repr]): Observer[Repr] = Observer(reader) 
} 

Với thông điệp "inferred type arguments [Repr] do not conform to method apply's type parameter bounds [Repr <: State[Repr]]". Kể từ khi các bằng chứng ev cho thấy cấu trúc này, tôi tự hỏi làm thế nào StateY có thể được cố định.

Trả lời

6

Vấn đề của bạn là mặc dù bằng chứng về hình thức A <:< B ngụ ý rằng một giá trị kiểu A có thể được chuyển đổi sang một giá trị kiểu B nó không bao hàm sự A <: B ... thực sự, lý do chính cho việc sử dụng một loại hạn chế hoặc một khung nhìn bị ràng buộc chứ không phải là một kiểu bình thường bị ràng buộc là chính xác bởi vì mối quan hệ kiểu phụ đó không giữ.

Do các hạn chế trong StateY, Repr <:< State[Repr], không đủ để đáp ứng các ràng buộc Repr <: State[Repr] trên apply phương pháp Observer 's. Cho rằng bạn muốn thư giãn ràng buộc trên tham số kiểu của StateX, tùy chọn duy nhất của bạn là làm suy yếu ràng buộc về tham số kiểu của phương thức apply tương ứng. Đem đến cho bạn một cái gì đó như sau sử dụng một cái nhìn bị ràng buộc thay vì một loại bình thường bị ràng buộc,

object Observer { 
    def apply[Repr <% State[Repr]](reader : Reader[Repr]) : Observer[Repr] = 
    new Observer[Repr] {} 
} 

hoặc cách khác,

object Observer { 
    def apply[Repr](reader : Reader[Repr]) 
       (implicit ev : Repr <:< State[Repr]) : Observer[Repr] = 
    new Observer[Repr] {} 
} 

nếu bạn muốn sử dụng hạn chế trong suốt.

5

Bằng chứng cho thấy rằng Repr có thể được chuyển đổi thành State[Repr]. Nó không nói gì về những gì có thể được thực hiện với Reader [Repr].

Không có phương pháp chung (độc lập của T) để chuyển đổi T [A] thành T [B] cho A => B. Điều đó có thể có khả năng cho một biến thể T, nhưng không có điều gì trong ngôn ngữ .