For instance,
List(1, 2, 3) match { case x :: y => (x, y) } In the code above, pattern matching will automatically find out that any non-empty List matches the case x :: y. I would like to know, why this happens?
As we all know, there is a :: method in List class. In addition, I find there is a :: case class in "list.scala":
/** A non empty list characterized by a head and a tail. * @param head the first element of the list * @param tl the list containing the remaining elements of this list after the first one. * @tparam B the type of the list elements. * @author Martin Odersky * @version 1.0, 15/07/2003 * @since 2.8 */ @SerialVersionUID(509929039250432923L) // value computed by serialver for 2.11.2, annotation added in 2.11.4 final case class ::[B](override val head: B, private[scala] var tl: List[B]) extends List[B] { override def tail : List[B] = tl override def isEmpty: Boolean = false } Therefore, we can write ::(1, Nil) to construct a new List. What's more, with the infix notation in Scala, we are able to equivalently write 1 :: Nil (although it turns out that Nil.::(1) will be invoked rather than ::(1, Nil), maybe owing to some precedence rules.)
As a result, I guess the case class :: has something to do with the pattern matching for :: (say, pattern x :: y will be matched by something like ::.unapply). But I did not find any unapply method or companion object for case class ::.
Could anyone please tell me whether my guess is correct? If not, how is the pattern matching for :: implemented in Scala?
Thanks!
EDIT:
Obviously, case class as :: is, a ::.unapply will be automatically generated for ::. Thus I can understand that case x :: y will match instance of :: (say, ::(1, 2)). But as we all know, case x :: y also matches all instances of type List, which is the base class of ::. Thus I think there might be some special unapply were my guess correct.
::.unapplyexists becauseunapplyis automatically generated for case classes, which::is.x :: ywill match a instance of::case class. But I can't figure out why it also matches a generalList, which is the base class of case class::.D.unapplyonly matches instance ofDbut not the base class of D.