假设我想要一个通用的抽象树类型,然后想要专门化它来创建特定类型的树。例如我可能有:
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。