2014-09-25 22 views
4

我試圖得到這樣的代碼如下工作:爲什麼這種類型的別名不能編譯(斯卡拉)

abstract class Vec[Self <: Vec[Self,T], T] { 
    this : Self => 
    def *(y : Self) : Self 
} 

abstract class LA[T] { 
    type V <: Vec[V, T] 
} 

object typetest2 { 
    def doesntcompile[L <: LA[Double]](x : L#V, y : L#V) : Unit = { 
     val z = x * y 
    } 

    def compiles[V <: Vec[V,_]](x : V, y : V) : Unit = { 
     val z = x * y 
    } 
} 

但是編譯器爲

[error] found : y.type (with underlying type L#V) 
[error] required: _9.V 
[error]   val z = x * y 
[error]     ^

是的這是一個失敗類型檢查或我做錯了什麼?

+0

有趣的問題。我試圖讓它編譯但失敗。但是我發現它也不能編譯爲一個更簡單的例子:如果你讓LA非泛型和非抽象,並用'class MyDouble(d:Double)替換'V型'擴展Vec [MyDouble,Double]' ,然後甚至刪除'doesntcompile'的泛型,並將'x'和'y'的類型更改爲'LA#MyDouble',它確實會失敗,而且對我來說編譯錯誤幾乎相同。以下是我嘗試的:http://pastie.org/9595425注意:你甚至可以擺脫'LB'並仍然得到相同的錯誤... – 2014-09-25 23:56:59

回答

2

雖然我不確定這種特殊情況沒有解決方法,但編譯器無法一般地告訴兩個路徑依賴類型即使它們是相同的。

你通常可以通過添加額外的類型參數解決這樣的情況:

def compiles2[V1 <: Vec[V1, _], L <: LA[Double]{type V = V1}](x: L#V, y: L#V) = { 
    val z = x * y 
} 

在某些情況下,你可能需要需要一個隱含的=:=Leibniz(Scalaz),讓編譯器傳遞的證據表明,兩種類型在鏈條上是平等的。