トップ «前の日記(2009-01-10 (Sat)) 最新 次の日記(2009-12-19 (Sat))» 編集 RSS feed

継続にっき

2004|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|12|
2006|01|03|05|06|08|09|10|12|
2007|01|02|03|05|07|12|
2008|10|
2009|01|05|12|
2010|04|05|11|
2011|01|09|12|
2012|02|03|05|09|12|
2013|02|03|
2014|05|09|
2015|12|
2017|09|

2009-05-17 (Sun)

))) Scalaパターンマッチング一覧

最近周りでScalaが盛り上がっているのでつられて勉強中。

パターンマッチングでどのようなものが使えるのかサンプル込みでまとめられた資料が 見あたらなかったので、仕様書を見つつメモ。 (まだ理解があやふやなので内容は怪しいですが。。)

8.1.1 Variable Patterns

var x = 0
var _ = 0

8.1.2 Typed Patterns

var x: Int = 0

8.2 Type Patternsに

The bottom types scala.Nothing and scala.Null cannot be used as type patterns, because they would match nothing in any case.

とあるように、Nothing、Nullは指定できない。

scala> null match { case x: Null => 0 }
<console>:6: error: this type cannot be used in a type pattern

でも、Nullは定義文としては使える。

scala> var x: Null = null
x: Null = null

他にもこのパターンはいろいろな書き方があるっぽいけど、 今は手に余るのでとりあえずパス。

8.1.3 Literal Patterns

0 match { case 0 => 1 }

定義文とmatch式で使えるパターンはほぼ同じようなので以下のようなことも可能。

var 0 = 0

8.1.4 Stable Identifier Patterns

2つの引数を受け取り値が等しいかどうかを判定する関数fを考える。

def f(x: Int, y: Int): Boolean = x match {
  case y => true
  case _ => false
}

上記のように書くと、「case y」のyがvariable patternと見なされるため 「case _」がerror: unreachable codeとなりコンパイルすら通らない。

これを回避するのがこのパターン。

  • 識別子をバッククォートで囲む
def f(x: Int, y: Int): Boolean = x match {
  case `y` => true
  case _ => false
}
  • 識別子を小文字以外で始める
def f(x: Int, Y: Int): Boolean = x match {
  case Y => true
  case _ => false
}

8.1.5 Constructor Patterns

case classによるマッチングのこと。

8.1.6 Tuple Patterns

scala> var (a, b) = (0, 1)
a: Int = 0
b: Int = 1

8.1.7 Extractor Patterns

unapply、unapplySeqを定義したオブジェクトを利用するマッチングのこと。 文法的にはConstructor Patternsと同じで以下のような感じ。

object A {
  def unapply(x: Int) = Some(x)
}

0 match {
  case A(0) => 0
  case _ =>    1
}
// => 0

1 match {
  case A(0) => 0
  case _ =>    1
}
// => 1

case classは「自動でapply、unapplyが定義されるクラス」と説明されることが多いが、 一応仕様としては別物のよう。

8.1.8 Pattern Sequences

簡単に言えば、Constructor PatternやExtractor Patternで@(Haskellのas-patternと同じ)や_*が使えるということかと。

scala> var List(a, b@_*) = List(1,2)
a: Int = 1
b: Seq[Int] = List(2)

8.1.9 Infix Operation Patterns

上記の中置記法版。

scala>  var a List b = List(1,2)
a: Int = 1
b: Int = 2

scala> var a List (b, c) = List(1,2,3)
a: Int = 1
b: Int = 2
c: Int = 3

この場合、_*は使えない。

scala> var a List (b, _*) = List(1,2,3)
<console>:1: error: illegal start of simple pattern

8.1.10 Pattern Alternatives

1 match { case 1 | 2 => 3 }

ちなみに「1 | _」は出来るけど、 「1 | x」はNG。

8.1.11 XML Patterns

scala> var <t>{a}</t> = <t>0</t>
a: scala.xml.Node = 0

8.1.12 Regular Expression Patterns

Scala 2.0以降は無くなった、とのこと。 ほかにもちょこちょこと書いてあるんだけど、具体的にどういうことなのかよく分からず。

8.1.13 Irrefutable Patterns

これも、いまいちよく分からない。。


2004|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|12|
2006|01|03|05|06|08|09|10|12|
2007|01|02|03|05|07|12|
2008|10|
2009|01|05|12|
2010|04|05|11|
2011|01|09|12|
2012|02|03|05|09|12|
2013|02|03|
2014|05|09|
2015|12|
2017|09|
トップ «前の日記(2009-01-10 (Sat)) 最新 次の日記(2009-12-19 (Sat))» 編集 RSS feed