6

编辑:感谢Derek指出错误消息的关键部分,我能够提取关键部分多一点,它似乎是关于存在类型。如果我的确了解§3.2.10正确的语言参考值的存量化量化,那么val m: Map[x.type#S, x.type#S] forSome { val x: T }val m: Map[t#S, t#S] forSome { type t <: T with Singleton }的简写。但在下面的代码中,它们的行为有所不同。覆盖与路径相关的类型参数的函数

trait Type { 
    type S 
} 

class Concrete extends Type { 
    type S = Double 
} 

trait BaseWorks { 
    type T <: Type 
    val m: t#S forSome { type t <: T with Singleton } 
} 

class Works extends BaseWorks { 
    override type T = Concrete 
    override val m = 0.0 
} 

trait BaseError { 
    type T <: Type 
    val m: x.type#S forSome { val x: T } 
} 

class Error extends BaseError { 
    override type T = Concrete 
    override val m = 0.0 
} 

精炼BaseWorks作品,而提炼BaseError导致错误error: overriding value m in trait BaseError of type Error.this.x.S forSome { val x: => Error.this.T }; value m has incompatible type。我是否误解了§3.2.10?

原帖:在下面的片的Scala代码编译器(2.9.0.1)产生一个错误说f2Derived覆盖没有什么方法。

abstract trait Type { 
    type T1 
    type T2 
    type P = (T1, T2) 
} 

class ConcreteType extends Type { 
    type T1 = Double 
    type T2 = Double 
} 

abstract class Base { 
    type T <: Type 
    type TP = T#P 
    def f1(v: TP): TP 
    def f2(v: T#P): T#P 
    def f3(v: T#P): T#P 
} 

class Derived extends Base { 
    override type T = ConcreteType 
    override def f1(v: TP): TP = v 
    override def f2(v: T#P): T#P = v 
    override def f3(v: TP): TP = v 
} 

在另一方面,覆盖功能f3用完全相同的签名所示的代码作品。我期望这两个函数的行为都是一样的。为什么不是这种情况?

+0

用Scala编译器打开bug https://issues.scala-lang.org/browse/SI-4914。 –

回答

5

(仅供参考,我使用2.9.0.1)

我一直没能找到在规范这样做的原因,但你的错误消息,至少,使得最终的原因不清楚。这是关键部分:

(Note that (_5.T1, _5.T2) forSome { val _5: Base.this.T } 
does not match 
(_16.T1, _16.T2) forSome { val _16: Base#T } 

Base.this.T不等同于Base#T。前者是基于实例this的路径相关类型,其中后者是不是基于实例的类型投影。

这似乎是由于类型解析的顺序。关于Base的评估解析TP,而关于Derived的评估解决T#P

如果有人可以指出规范中可以正确解释的位置,我很乐意阅读它。

+0

嗨德里克。感谢您指出关键部分。我能够更多地提取关键部分。我会更新上面的帖子。 –