2011-04-03 46 views
12

Tôi đang tuyệt vọng cố gắng giải quyết như sau:một phần áp dụng các tham số kiểu

trait Access[Res[_]] { def access[C]: Res[C] } 

trait CList[C1, A] extends Access[CList[_, A]] // ?! 

def test[C1, C2, A](c: CList[C1, A]): CList[C2, A] = c.access[C2] 

scalac chỉ nói: "error: illegal cyclic reference involving trait CList". làm thế nào tôi có thể làm cho biên dịch này?

Trả lời

13

Bạn có thể quan tâm đến loại lambdas Việc áp dụng một phần mà bạn sử dụng trong câu trả lời của bạn thực sự là implemented in scalaz Do mã có xu hướng ít được đọc hơn, nên họ bắt đầu sử dụng loại lambdas thay thế. Loại câu hỏi có thể được viết là

({type λ[α] = CList[α,A]})#λ 

Điều này hoạt động bằng cách tạo một phép chiếu kiểu trên kiểu tham số λ bên trong một loại cấu trúc, do đó nắm bắt tham số kiểu bên ngoài (trong trường hợp này là A).

Các vấn đề khác liên quan đến phương sai được mô tả trong câu trả lời của bạn có thể được giải quyết bằng cách thực hiện tham số Res trong Access sovariant.

Sau những thay đổi mã của bạn sẽ trông như thế này:

trait Access[+Res[_]] { def access[C] : Res[C]} 

trait CList[C, +A] extends Access[({type λ[α] = CList[α,A]})#λ] 
+0

Cảm ơn, trông tốt hơn một chút. Ngoài ra, trong trường hợp thực sự của tôi, các tham số kiểu của CList có giới hạn trên, có một đặc điểm riêng biệt Partial2 không thực sự hữu ích (tôi sẽ cần phải thêm các tham số kiểu cho các giới hạn, vv) –

+0

Ngoài ra nếu loại lambda được sử dụng thường xuyên trong mã của bạn, xem xét plugin trình biên dịch sau: https://github.com/non/kind-projector –

2

googling cho "ứng dụng loại phần" tôi tìm thấy giải pháp này được đăng bởi James Iry thuộc danh scala cuộc tranh luận (http://scala-programming-language.1934581.n4.nabble.com/Partial-type-inference-td2007311.html; điều chỉnh để trình tự arg được thay đổi):

type Partial2[T[_,_], B] = { 
    type Apply[A] = T[A,B] 
} 
trait CList[C1, A] extends Access[Partial2[CList, A]#Apply] 

pho mát louise, đây có phải là cách duy nhất để làm điều đó trong scala vào năm 2011? !!

EDIT:

này không thành công với hiệp phương sai trong A:.., - (

trait Access[Res[_]] { def access[C]: Res[C] } 

type Partial2[T[_,_], B] = { 
    type Apply[A] = T[A,B] 
} 
trait CList[C1, +A] extends Access[Partial2[CList, A]#Apply] 

"covariant type A occurs in invariant position" 
0

Tôi biết đây là một câu hỏi thực sự cũ, nhưng dù sao:

trait AnyAccess { 
    type Res[X] 
    def access[Z]: Res[Z] 
} 

trait AnyCList extends AnyAccess { me => 
    type C 
    type A 
    // this could be a subtype bound instead, if needed 
    type Res[X] = AnyCList { type C = X; type A = me.A } 
} 
case object AnyCList { 
    type of[C0, +A0] = AnyCList { type C = C0; type A <: A0 } 
} 

case object buh { 

    def test[C1, C2, A](c: AnyCList.of[C1, A]): AnyCList.of[C2, A] = c.access[C2] 
} 
Các vấn đề liên quan