Mat*_*ner 6 scala abstract-data-type existential-type path-dependent-type
编辑:感谢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
}
Run Code Online (Sandbox Code Playgroud)
精炼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)产生一个错误,说该方法f2不会覆盖任何内容Derived.
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
}
Run Code Online (Sandbox Code Playgroud)
另一方面,f3使用与代码中显示的完全相同的签名覆盖函数.我希望这两个函数的行为方式相同.为什么不是这样?
(仅供参考,我使用的是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 }
Run Code Online (Sandbox Code Playgroud)
Base.this.T不等于Base#T.前者是基于实例的路径依赖类型,this其中后者是不基于实例的类型投影.
这似乎是由于类型分辨率的顺序. TP在评估方面得到了解决,Base而在评估方面得到了T#P解决Derived.
如果有人可以指出规范中可以正确解释的位置,我很乐意阅读它.