2011-10-15 6 views
0

En Scala, je voudrais être en mesure de définir un type générique de nœuds d'arbre de syntaxe abstraite un peu comme ceSpécialiste Types Sealed génériques

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 
} 

Maintenant, je peux écrire du code générique comme celui-ci

def countLeaves[T <: AST[T]](x : AST[T]) : Int = x match { 
    case LeafAST(x) => 1 
    case BranchAST(left, right) => countLeaves[T](left) + countLeaves[T](right) 
} 

Maintenant, mon premier problème est que le mot-clé sealed semble n'avoir aucun effet. Si je omets un cas de l'expression de correspondance, il n'y a pas d'erreur. Pourquoi et comment puis-je écrire ce que je veux? (J'ai d'autres problèmes - par exemple, comment spécialiser AST--, mais je vais juste coller à un problème par poste.)

+2

Quelle version de Scala utilisez-vous? 2.9.1.final ne semble pas avoir ce problème. Je reçois l'avertissement "match is not exhaustif" comme prévu. (BTW c'est un avertissement et pas une erreur.) – agilesteel

+0

En raison de votre réponse j'ai mis à niveau vers le plug-in Eclipse à http://download.scala-ide.org/releases/2.0.0-beta avec un outil 2.9.2 -chaîne. Toujours pas de message _warning_ si je rate un cas. –

+1

La version bêta du plug-in Eclipse est en cours de développement et manque donc de nombreuses fonctionnalités. J'ai utilisé le REPL et comme je l'ai dit plus tôt, cela semble fonctionner. – agilesteel

Répondre

0

Il n'y a pas d'erreur - il ya un avertissement. Par exemple:

scala> :paste 
// Entering paste mode (ctrl-D to finish) 

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 
} 

// Exiting paste mode, now interpreting. 

defined class AST 
defined class LeafAST 
defined class BranchAST 

scala> def countLeaves[T <: AST[T]](x : AST[T]) : Int = x match { 
    |  case LeafAST(x) => 1 
    | } 
<console>:10: warning: match is not exhaustive! 
missing combination  BranchAST 

     def countLeaves[T <: AST[T]](x : AST[T]) : Int = x match { 
                 ^
countLeaves: [T <: AST[T]](x: AST[T])Int 

Vous pouvez le transformer en une erreur avec le drapeau -Xfatal-warnings.

+0

Merci. Soit j'étais complètement confus ou j'avais besoin de mettre à jour mon système. De toute façon, je vois l'avertissement maintenant. Merci à Daniel et agilesteel. –