blog.petitviolet.net

Scala - パターンマッチにおけるアットマーク(@)

2014-05-23

QiitaScala

参照

http://stackoverflow.com/questions/4513380/scala-match-help

問題

こんなコードがある

def flatMapSublists[A,B](ls: List[A])(f: (List[A]) => List[B]): List[B] =
  ls match {
    case Nil => Nil
    case sublist@(_ :: tail) => f(sublist) ::: flatMapSublists(tail)(f)
  }

ん?sublist@(_ :: tail)???

意味

パターンマッチを行う際にfoo@barで、barにマッチしたものをfooにバインドするということらしい つまり、上の例ではls_ :: tailにマッチするようなものだった場合に、lssublistにバインドされる

他の例

参照 URLで出されている例そのままだが、リストに 3 つの要素があるかどうか確認し、 そうであった場合に、標準出力しながら、リストの 2 番目(index は 1)の要素を取得したいとき

val something = List(1, 2, 3)
something match {
  case ls@List(_,elem,_) => println("matching:" + ls); elem
  case _ => println("not found")
}
// res: AnyVal = 2

// @を使わずに同様のことを行う
something match {
  case List(a,elem,b) => println("matching:" + List(a,elem,b)); elem
  case _ => println("not found")
}
// res: AnyVal = 2

// これでも良い
something match {
  case List(a,elem,b) => println("matching:" + something); elem
  case _ => println("not found")
}

ls@なんて付けずにsomethingをそのまま使えばいいんじゃね?って思った よくわからんのでもう少し

val list = List(1, 2, 3)

list match {
  case ls@(h :: tail) => println(tail); list
  case Nil => Nil
}
// List(2, 3)
// res: List[Int] = List(1, 2, 3)

list match {
  case ls@(h :: tail) => println(tail); ls
  case Nil => Nil
}
// List(2, 3)
// res: List[Int] with Serializable = List(1, 2, 3)

なぜかSerializableになった この@には名前がないのかな

from: https://qiita.com/petitviolet/items/89843d948b6fc06eba57