kmizuの日記

プログラミングや形式言語に関係のあることを書いたり書かなかったり。

初学者向けの Scala Tips (5) - パターンマッチと無名関数の組み合わせを簡潔に書く

Scala初学者の方が書くコードには、しばしば以下のようなものが散見されます。

list.map {x =>
  x match {
    case A =>
    case B =>
    case _ =>
  }
}

無名関数を作るための構文である{x => ...}exp match { case ... }を別々に考えるとこのようなコードになるのは無理はありません。しかし、これはもっと簡潔に書くことができます。改良したのが以下のコードです。

list.map {
  case A =>
  case B =>
  case _ =>
}

前者の書き方に比べて断然簡潔ですね。特別な事情がない限り、無名関数の引数を即座にパターンマッチする必要がある場合、後者の書き方を使いましょう。

ちなみに、この書き方を教えると結構びっくりされる方が多いようで、この構文はPartialFunctionのためのものだと思っていた、ということのようです。確かに、この{ case .... }という構文は、PartialFunction[-A, +B]型のオブジェクトを作るためにも使われます。ただし、それが適用されるのは、左辺がPartialFunction型を要求しているときのみ、つまり

  • (代入/初期化)の左辺がPartialFunctionである
  • メソッドの仮引数がPartialFunctionである

時に限られます。それ以外の場合、

list.map {
  case A => /* A */
  case B => /* B */
  case _ => /* _ */
}

というコードは以下のコードと同じように解釈されます。

list.map {x =>
  x match {
    case A => /* A */
    case B => /* B */
    case _ => /* _ */
  }
}

ちなみに、IntelliJ IDEAは前者の形のコードを検出して、後者の形に変換することを提案する機能を持っているのですが、その名前が「Convert match statement to partial function」という名前です。思わず、誤解を招く名前を付けるなよ!とつっこみたくなりました。