假设我想要一个通用的抽象树类型,然后想要专门化它来创建特定类型的树。例如,我可能有:
sealed abstract class AST[T <: AST[T]] {
def child : List[T] ;
}
case class LeafAST[T <: AST[T]]( x : Int ) extends AST[T] {
def child = Nil
}
case class BranchAST[T <: AST[T]]( left : T, right : T ) extends AST[T] {
def child = left :: right :: Nil
}
现在我想要一个特定的版本,为每个类添加一个“类型”字段。所以我们来介绍一个Typed
特征。
trait Typed { var ty : Type = NoType }
如何定义具有此特征的三个类AST,BranchAST和LeafAST的特定版本?
第一次尝试。使用Scala的类型成员功能。类型成员必须是某些东西的成员,因此对象定义
object TypedASTObj {
type TypedAST = AST[TypedAST] with Typed ;
type TypedLeafAST = LeafAST[TypedAST] with Typed ;
type TypedBranchAST = BranchAST[TypedAST] with Typed ;
}
这会产生错误“涉及TypedAST类型的非法循环引用”。
第二次尝试。这次我开始一个新文件并放入
abstract sealed trait TypedAST extends AST[TypedAST] with Typed ;
case class TypedLeafAST( override val x : Int ) extends LeafAST[TypedAST](x) with TypedAST{ }
case class TypeBranchAST( override val left : TypedAST, override val right : TypedAST ) extends BranchAST[TypedAST](left, right) with TypedAST { }
但是当然这会产生错误“密封类AST的非法继承”,因为TypedAST扩展了另一个文件中定义的密封类AST。我真的不想从AST继承; 2我想做的就是把它专门化。继承只是达到目的的手段。 (顺便说一句,我并不确定密封的特性是我想要的。我之所以把它作为一个特性而不是一个类,是因为TypedLeafAST需要扩展TypedAST和LeafAST。)
我正在使用Scala 2.9.1和2.9.2。