2011-10-15 43 views
0

在Scala中,我希望能夠定義一個通用型抽象語法樹節點的排序是這樣專業通用密封類型

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 
} 

現在我可以寫通用這樣的代碼

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) 
} 

現在我的第一個問題是關鍵字sealed似乎沒有效果。如果我從匹配表達式中省略了一個案例,那就沒有錯誤。爲什麼和如何寫我想要的東西? (我有其他問題 - 例如如何專門化AST--,但我只會堅持每個職位一個問題。)

+2

您使用的是什麼Scala版本? 2.9.1.final似乎沒有這個問題。如預期的那樣,我得到了「比賽並非詳盡無遺」的警告。 (順便提一下,這是一個警告,不是錯誤。) – agilesteel

+0

由於您的回覆,我使用2.9.2工具升級到Eclipse插件http://download.scala-ide.org/releases/2.0.0-beta -鏈。如果我錯過了一個案例,仍然沒有_warning_消息。 –

+1

Eclipse插件測試版正在積極開發中,因此缺少許多功能。我使用了REPL,正如我之前所說,它似乎有效。 – agilesteel

回答

0

沒有錯誤 - 有一個警告。例如:

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 

您可以將其變成帶有標記-Xfatal-warnings的錯誤。

+0

謝謝。要麼我完全困惑,要麼升級我的系統。無論哪種方式,我現在看到警告。感謝Daniel和agilesteel。 –