【发布时间】:2013-09-28 03:53:15
【问题描述】:
我在路径相关类型和模式匹配方面遇到问题:
trait View[A]
trait Foo {
type Bar
def defaultBar: Bar
}
trait Baz extends Foo {
def view(init: Bar): View[Bar]
}
trait Test {
val foo: Foo
def bar: foo.Bar = foo.defaultBar
def test(): Option[View[foo.Bar]] =
foo match {
case b: Baz => Some(b.view(bar))
case _ => None
}
}
这会失败,因为 scalac 无法将 foo 识别为 b。因此,它只适用于两种强制转换:
case b: Baz => Some(b.view(bar.asInstanceOf[b.Bar]).asInstanceOf[View[foo.Bar]])
肯定有一个干净的方法来避免演员表吗?
【问题讨论】:
-
我不确定,但这样的类型转换不违反路径依赖类型的逻辑吗?那为什么不使用带协方差的类型投影呢?
-
我不能使用投影,因为基本成员类型太笼统了。这只有在我真正想避免的
trait Foo[F <: Foo[F]] { type Bar; def defaultBar: F#Bar }的圈子里才有效。 -
您是否缺少来自
Baz的一些代码?在上面的这个示例中,您永远不会将Baz定义为Bar的类型。您的测试与Foo匹配,但您的代码永远不会使Baz成为有效的Foo。 -
@iain
Baz是Foo的子类型。如果我匹配foo并发现它是Baz的一个实例,显然是b eq foo。
标签: scala casting path-dependent-type subtyping