我想用抽象类型定义一个抽象递归数据结构。像这样的东西:
case class ParentA( name : String, children : List[ParentA] ) extends Parent {
type PARENT = ParentA
}
case class ParentB( name : String, children : List[ParentB] ) extends Parent {
type PARENT = ParentB
}
sealed abstract class Parent {
// we'd like to Define Parent as a PARENT
// something like:
// this : PARENT =>
type PARENT <: Parent
val name : String
val children : List[PARENT]
def findParent(name:String) : Option[PARENT] = {
if( name == this.name ) {
Some(this) // ouch
} else {
// re-ouch
children.flatMap( f => f.findParent(name) )
}
}
}
val a2a : ParentA = ParentA("a",List(ParentA("a1",Nil),ParentA("a2",List(ParentA("a2a",Nil))))).findParent("a2a").get
当然这不会编译,因为编译器无法猜测 Parent.this 是 PARENT 。
error: type mismatch;
found : Parent.this.type (with underlying type this.Parent)
required: Parent.this.PARENT
Some(this)
并且
error: type mismatch;
found : List[Parent.this.PARENT#PARENT]
required: Option[Parent.this.PARENT]
children.flatMap( f => f.findParent(name) )
我可以通过在这里和那里进行转换来解决它,但最好能够告诉编译器 Parent 是 PARENT。或者也许我错过了一些东西:)
编辑 - 泛型
我忘了提到泛型不是一种选择。这个例子实际上是一个更微妙问题的简化版本。使用泛型将导致程序的二次增长。这是一个链接,解释了为什么泛型并不总是可行的替代方案:Scala:抽象类型与泛型。
基本上我最好使用抽象类型 - 甚至既不使用抽象类型也不使用泛型 - 和强制转换。