在最新发布的scala(2.12.x)中,路径依赖类型的实现是否不完整?
In the latest release of scala (2.12.x), is the implementation of path-dependent type incomplete?
我做了一个快速实验来理解 scala 的路径依赖类型特性的本质:
trait SS {
type II
}
class SS1() extends SS {}
def sameType[T1, T2](implicit ev: T1 =:= T2): Unit = {}
// experiments start here
val a = new SS1()
val b = new SS1()
val c = a
sameType[a.II, a.II]
assertDoesNotCompile(
"""
|sameType[a.II, b.II]
|""".stripMargin
) // of course it happens
到目前为止还好吗?直到我输入下一行:
sameType[a.II, c.II]
此时编译器给出了以下错误:
[Error] .../PathDependentType/ProveSameType.scala:32: Cannot prove that a.II =:= c.II.
one error found
尽管常量 a 和 c 总是引用 2 个完全相同的对象。那么为什么scala编译器选择不证明呢?这是否意味着 a & c 指的是 2 个不同的 'paths',并且出于实用性的考虑,这种行为是预期的?
这是绝对正确的行为。 a
和 c
的引用相等性无关紧要。路径依赖类型 a.II
和 c.II
不同。
a.II
, c.II
are shorthands 对于类型 a.type#II
, c.type#II
和单例类型 a.type
, c.type
是不同的也是。
路径https://scala-lang.org/files/archive/spec/2.13/03-types.html#paths
类型等价https://scala-lang.org/files/archive/spec/2.13/03-types.html#equivalence
我做了一个快速实验来理解 scala 的路径依赖类型特性的本质:
trait SS {
type II
}
class SS1() extends SS {}
def sameType[T1, T2](implicit ev: T1 =:= T2): Unit = {}
// experiments start here
val a = new SS1()
val b = new SS1()
val c = a
sameType[a.II, a.II]
assertDoesNotCompile(
"""
|sameType[a.II, b.II]
|""".stripMargin
) // of course it happens
到目前为止还好吗?直到我输入下一行:
sameType[a.II, c.II]
此时编译器给出了以下错误:
[Error] .../PathDependentType/ProveSameType.scala:32: Cannot prove that a.II =:= c.II.
one error found
尽管常量 a 和 c 总是引用 2 个完全相同的对象。那么为什么scala编译器选择不证明呢?这是否意味着 a & c 指的是 2 个不同的 'paths',并且出于实用性的考虑,这种行为是预期的?
这是绝对正确的行为。 a
和 c
的引用相等性无关紧要。路径依赖类型 a.II
和 c.II
不同。
a.II
, c.II
are shorthands 对于类型 a.type#II
, c.type#II
和单例类型 a.type
, c.type
是不同的也是。
路径https://scala-lang.org/files/archive/spec/2.13/03-types.html#paths
类型等价https://scala-lang.org/files/archive/spec/2.13/03-types.html#equivalence