部分関数

よくわからないものが出てきた。説明の前に使い方を見てみよう。

scala> List(1,2,3,4,5).collect { case i if i % 2 == 1 => i * 2 }
res0: List[Int] = List(2, 6, 10)

リストの collect メソッドは match 式の { } で囲まれたブロックの部分だけを引数にとって、条件に合う要素だけを抜き出し、=> の右の式を適用した新しいリストを返す(でいいのかな)。この引数が部分関数(PartialFunction)らしい。

引数、とさらっと言ったけど、引数はカッコに囲まれていない。あっちゃダメなのかと思ったらそうでもないようだ。

scala> List(1,2,3,4,5).collect({ case i if i % 2 == 1 => i * 2 })
res1: List[Int] = List(2, 6, 10)

collect メソッドの動作はわかるんだけど、その引数が部分関数だといわれてもちょっとピンとこない。部分関数ってどうして部分?

もうちょっと厳密に言うと、引数に書いてあるブロック式自体は部分関数ではなくて、この式から部分関数が生成されるようだ。一般には case が複数あって、どれかのパターンにマッチしたときだけ新しい値がつくられてリストの要素になる。

てことは、こんなふうにも書けるわけだ。

scala> List(1,2,3,4,5).collect {
     |     case i if i % 2 == 0 => i * 2
     |     case i if i % 2 == 1 => i * i
     | }
res2: List[Int] = List(1, 4, 9, 8, 25)

うん、期待通りの動作はしてる。

でも、やっぱりなんで部分関数っていうんだかわからないなぁ。