kmizuの日記

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

partial functionについて訂正

Scala勉強会@関東-1のときに、

{ case 1 => "A"
  case 2 => "B"
}

のような式が、それ単体でpartial functionのリテラルであるというような説明をしていましたが、今日、Scala Language Specificationの該当箇所(8.5 Pattern Matching Anonymous Functionsの辺り)を読んでいたら、それが勘違いであることに気付きました。間違った説明をしてすいませんでした。p.114から関連する箇所を引用すると、まず、期待されている型がscala.Functionk[S1, . . . , Sk, R]である場合、つまり、通常のfunction typeである場合、

If the expected type is scala.Functionk[S1, . . . , Sk, R] , the expression is taken to be equivalent to the anonymous function:

(x1 : S1, ..., xk : Sk) => (x1, ..., xk) match {
  case p1 => b1 ... case pn => bn
}

ということで、通常の無名関数とパターンマッチの組み合わせに展開されます。一方、期待されている型がscala.PartialFunction[S, R]である場合、

If the expected type is scala.PartialFunction[S, R], the expression is taken to be equivalent to the following instance creation expression:

new scala.PartialFunction[S, T] {
  def apply(x: S): T = x match {
    case p1 => b1 ... case pn => bn
  }
  def isDefinedAt(x: S): Boolean = {
    case p1 => true ... case pn => true
    case _ => false
  }
}

となり、isDefinedAtメソッドを持ったpartial functionが生成される、ということのようです。