Scala可以注意到路径依赖类型之间的身份吗?

Sco*_*son 4 types scala inner-classes path-dependent-type

有时在Scala中我发现我得到与路径依赖类型相关的类型不匹配,但我可以轻易地推断出事实上类型是一致的.这是一个简单的例子:

trait Foo { trait Bar }

object Main extends App {
  val foo1 = new Foo { }
  val foo2 = foo1

  def turkle(x: foo1.Bar) {}

  turkle(new foo2.Bar {})
}
Run Code Online (Sandbox Code Playgroud)

它给出:"类型不匹配;找到:需要Main.foo2.Bar的java.lang.Object:Main.foo1.Bar".

当然现在的路径Main.foo1.BarMain.foo2.Bar必须一致,因为我们写的val foo2 = foo1.我们可以通过将最后一行更改为来验证这一点

turkle((new foo2.Bar {}).asInstanceOf[foo1.Bar])
Run Code Online (Sandbox Code Playgroud)

这两个编译和运行没有例外.

Scala可以自动执行这样的推理吗?如果是这样,我怎么能做到这一点?

(如果没有,是否有任何前景可以将类型系统扩展到这个方向?)

我会注意到,有时斯卡拉确实出现执行这种推理.假设我trait Foo改为object Foo:

object Foo { trait Bar }

object Main extends App {
  val foo1 = Foo
  val foo2 = foo1

  def turkle(x: foo1.Bar) {}

  turkle(new foo2.Bar {})
}
Run Code Online (Sandbox Code Playgroud)

现在一切都编好了:不知何故,Scala已经解决了两者Main.foo1.Bar并且Main.foo2.Bar真的相同Foo.Bar.

rxg*_*rxg 5

Iulian Dragos 在最近的一个问题中给出了你需要的答案.简短的版本是编译器不进行流分析,所以在你的第一个例子中它不能告诉foo1.Bar和foo2.Bar是相同的类型,因为foo1和foo2只是Foo类型.但是在第二个例子中,foo1被推断为单例类型Foo.type(Foo的子类型),因此事情按预期工作.

您可以通过将foo2声明为foo1的单例类型来使您的第一个示例工作:

val foo2:foo1.type = foo1
Run Code Online (Sandbox Code Playgroud)

请参阅Scala语言规范2.9的第3.2.1节以供参考.