Предположим, я хочу общий абстрактный тип дерева, а затем хочу специализировать его для создания определенных типов деревьев.Например, у меня может быть:
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.