2014-09-25 51 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),让编译器传递的证据表明,两种类型在链条上是平等的。