型によるパターンマッチ

2019年5月7日
1 分

match 式では、値の型によるパターンマッチもできる。パターンには変数の後に : に続けて型を書く。こんなふうに。

scala> val obj: AnyRef = "String Literal"  
obj: AnyRef = String Literal  
  
scala> obj match {  
     |     case v:java.lang.Integer =>  
     |         println("Integer!")  
     |     case v:String =>  
     |         println(v)  
     | }  
String Literal

AnyRef という型は、あらゆる参照型を代入できる型。よくわからないけどとりあえずそういうものだと思っておく。

で、この例では値の実体が文字列なので、初めの java.lang.Integer にはマッチせず、2番目の String にマッチしている。値は変数 v に束縛されるので後から使うことができる。

さて、ここで疑問なのは、どうして java.lang.Integer なんて型がいきなり出てきたかってこと。Int じゃダメなのか。試してみよう。

scala> obj match {  
     |     case v:Int =>  
     |         println("Int!")  
     |     case v:String =>  
     |         println(v)  
     | }  
<console>:14: error: pattern type is incompatible with expected type;  
 found   : Int  
 required: Object  
           case v:Int =>  
                  ^

ダメだった。なんかパターンの型の互換性がどうとか言ってる。Object を期待しているところに Int が来たと。

なんというか、まだ Scala の型システムについて理解してないんだけど、いきなり Java の型が出てくるのは気持ちが悪い。Scala の型だけで済ますことはできないんだろうか。