Search code examples
scalapattern-matchingunapply

What is the difference between unapply and unapplySeq?


Why does Scala have both unapply and unapplySeq? What is the difference between the two? When should I prefer one over the other?


Solution

  • Without going into details and simplifying a bit:

    For regular parameters apply constructs and unapply de-structures:

    object S {
      def apply(a: A):S = ... // makes a S from an A
      def unapply(s: S): Option[A] = ... // retrieve the A from the S
    }
    val s = S(a)
    s match { case S(a) => a } 
    

    For repeated parameters, apply constructs and unapplySeq de-structures:

    object M {
      def apply(a: A*): M = ......... // makes a M from an As.
      def unapplySeq(m: M): Option[Seq[A]] = ... // retrieve the As from the M
    }
    val m = M(a1, a2, a3)
    m match { case M(a1, a2, a3) => ... } 
    m match { case M(a, as @ _*) => ... } 
    

    Note that in that second case, repeated parameters are treated like a Seq and the similarity between A* and _*.

    So if you want to de-structure something that naturally contains various single values, use unapply. If you want to de-structure something that contains a Seq, use unapplySeq.