Scalaのmatch式(1)

最初にScalaのmatch式を見たいと思います.有名なMartin Odeskey教授は邦名「Scalaスケーラブルプログラミング(インプレス刊)」で次のように記しています.

Scalaのmatch式を使えば、他の言語のswitch文と同じように、いくつかの選択肢(alternative)から1つを選ぶといった処理ができる。一般に、match式では任意のパターンを使って選択肢を記述できる。(p.140)」

Javaのswitchは、次のように書く。

 switch (<セレクター式>) { <選択肢> }

一方、match式は次のようになる。

 <セレクター式> match { <選択肢> }

パターンマッチには、caseキーワードを先頭に置く一連の選択肢(alternative)が含まれている。個々の選択肢には、パターン(pattern)と1つ以上の式が含まれており、パターンがマッチするとそれらの式が評価される。パターン式は、=>の矢印記号で区切られている。(p.263)」

しかしScalaのmatch式はJavaなどのswitch文よりはるかに強力です.Scalaのパターンには「定数パターン」、「変数パターン」「ワイルドカードパターン」「コンストラクターパターン」があるとされています.定数パターンは定数とマッチします.変数パターンはすべての値にマッチし、変数で値を参照できます.ワイルドカードパターンの_もすべての値にマッチしますが値を参照する変数を持ちません.

もっとも強力と思われるのはコンストラクタパターンではないでしょうか?こんなのJavaでは考えも及びません.詳細は本をご覧いただくとして、

abstract class Expr
case class Var(name:String) extends Expr // 文字列
case class Number(num:Double) extends Expr // 数値
case class UnOp(operator: String, arg: Expr) extends Expr // 単項演算
case class BinOp(operator: String, left: Expr, right: Expr) extends Expr // 二項演算

という算術式を定義するケースクラスというものを定義して、コンストラクタをパターンにかけます.

def simplifyTop(expr: Expr): Expr = expr match {
  case UnOp("-",Unop("-",e)) => e // 負の数の負は元のまま
  case BinOp("+", e, Number(0)) => e // 0の加算は元のまま
  case BinOp("*", e, Number(1)) => e // 1の乗算は元のまま
  case _ => expr
}

まさに「オブジェクトの内容までパターンとマッチするかチェックされる」のです.

「コンストラクタパターンを見ると、パターンマッチの威力を心底感じるだろう。(p.267)」

まさにそのとおりです.

ではXMLの場合はどうなのでしょうか?

XMLパターンは、XMLリテラルと似ている。最大の違いは、{}のエスケープを挿入したときに{}の中のコードが式でなくパターンになることである。{}に組み込まれたパターンは、新しい変数への束縛、型テストの実行、_や_*パターンによる内容の無視など、Scalaのパターン言語をフルに使うことが出来る。」

紹介されている例をは以下のものです.

def proc(node: scala.xml.Node): String =
  node match {
    case <a>{contents @ _*}</a> => "It's an a: "+ contents //要素aにマッチし子ノードを変数contentsに束縛
    case <b>{contents @ _*}</b> => "It's an b: "+ contents //要素bにマッチし子ノードを変数contentsに束縛
    case _ => "It's something else." //その他のパターン
}

でもちょっと待っていただきたいのです.私のやりたいのは、XSLTスタイルシートのテンプレートのパターンのようなものをmatch式に応用できるかです.あまり変数の束縛には興味はありません.実際変数への束縛には何か違和感があります.

実際にやりたいのは、例えば

1.ネームスペース付きの要素をmatch式で扱う.
2.属性yearの値が"1994"のmusicLibrary要素にマッチさせる.

というようなことです.本を読んでいても、どうしてもこういう実際の現場の要求に答えた記述に出会えません.これらをもう少し詳しく見てゆきたいと思います.