2011-07-22 71 views
3

爲什麼這個Scala代碼無法檢測?爲什麼這些類型參數不符合類型細化?

trait T { type A } 
trait GenFoo[A0, S <: T { type A = A0 }] 
trait Foo[S <: T] extends GenFoo[S#A, S] 

我不明白,爲什麼 「類型的參數[S#A,S]不符合特質GenFoo的類型參數界限[A0,S <:T {類型A = A0}]」。有沒有解決辦法?

編輯:正如已經指出的,一致性錯誤源於未驗證S <: T{type A = S#A}。丹尼爾索布拉爾指出-explaintypes,它告訴我們:

S <: T{type A = S#A}? 
    S <: T? 
    true 
    S specializes type A? 
    this.A = this.A? 
     S = this.type? 
     false 
    false 
    false 
false 

我不知道如何解釋這一點。

注意,我們得到了一個非法的循環引用,如果我們試圖定義,

trait Foo[S <: T { type A = S#A } ] extends GenFoo[S#A, S] 

雖然這裏的類型精化似乎並沒有添加任何新的信息。 (也Why is this cyclic reference with a type projection illegal?見)

我的動機是創造一個特點Foo[S <: T],專門對S#A,如:How to specialize on a type projection in Scala?爲了得到這個工作,我試圖浮出水面S#A作爲實施特質GenFoo明顯的參數A0,這可以直接專業化。我希望將Miles Sabin的答案應用於Why is this cyclic reference with a type projection illegal?,但我遇到了這種一致性錯誤。

+0

你有沒有試過-explaintypes? –

+0

感謝您的指針。我更新了問題以包含-explaintypes的輸出。 –

回答

1

這似乎是答案:

小號專業A型?

問題有關專門來自這裏:T { type A = A0 }。這是類型Ttype A專門 - 意思是,它比原來的T更受限制。

該問題的答案是否定的 - S沒有限制,它是專門的。

+0

我感到驚訝的是'S <:T'和'S <:T {type A = S#A}'有區別。儘管後者是專門化的,但似乎這種專業化並沒有對'S'增加額外的限制。 (也許有人暗示後者會產生一個非法循環引用錯誤,如果有人試圖直接使用它)。也許我誤解了這些類型的含義,但看起來這是Scala類型中一個實用而非基本的限制系統? –

1

爲了符合類型限制,S必須是T { type A = A0 }的子類型,但它只是T的子類型。

+0

但是在這種情況下'A0 = S#A',所以我期望'S <:T {type A = S#A}' –

1

我不是這個主題的專家,我只是玩弄你的代碼,發現問題不是S#A部分,而是S部分。

如果你寫這樣的代碼:

trait T { type A } 
trait GenFoo[A0, S <: T] // the { type A = A0 } part is not there anymore 
trait Foo[S <: T] extends GenFoo[S#A, S] 

然後再編譯,因爲SFoo[S <: T]符合在GenFoo[A0, S <: T]S

在您的例子編譯器知道ST一個亞型,因此具有確定的type A,但它不來的地步,它可以驗證在SAS#A

+0

謝謝。我更新了問題以包含此信息。 –

相關問題