0

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

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。

4

0 回答 0