scalapattern-matchingseqextractor

No pattern match for Seq[Seq[T]]


def example1(sss:Seq[Seq[String]]) = sss match {
  case Seq(a, b) :+ Seq(c, d) :+ tail => true
}

val res1 = example1(Seq(Seq("a", "b"), Seq("c","d")))
// scala.MatchError: List(List(a, b), List(c, d)) 

Well I have a workaround, which is to use

case Seq(Seq(a, b), Seq(c, d), _*) => true

Can anyone explain why the first doesn't work?


Solution

  • You are using the wrong extractor! :+ implies that the first part is part of the (outer) Seq, hence a and b are of type Seq[String] rather than String, while the second part Seq(c,d), and tail are treated as elements, so c and d are in fact String.

    Normally this wouldn't type check, but in the case where the element type is a Seq, it does. However if you assume a and b are String, and try to treat them as such, the type checker might complain, causing more confusion.

    The correct extractor is +:. The colon goes on the side of the sequence, and the plus on the side of the element. Hence

      case Seq(a, b) +: Seq(c, d) +: tail => true
    

    matches as expected.