专业通用密封类型。第1部分

时间:2011-10-15 23:38:28

标签: generics scala types sealed

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

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。

0 个答案:

没有答案