Соответствие шаблону "случай Nil" для Vector

После прочтения этого сообщения о том, как использовать сопоставление шаблонов в Vector (или любой коллекции, реализующей Seq), я проверил соответствие шаблонов в этой коллекции.

scala> x // Vector
res38: scala.collection.immutable.Vector[Int] = Vector(1, 2, 3)

scala> x match {
     |    case y +: ys => println("y: " + "ys: " + ys)
     |    case Nil => println("empty vector")
     | }
<console>:12: error: pattern type is incompatible with expected type;
 found   : scala.collection.immutable.Nil.type
 required: scala.collection.immutable.Vector[Int]
Note: if you intended to match against the class, try `case _: <none>`
                 case Nil => println("empty vector")
                      ^

Здесь dhg ответ, который объясняет +::

object +: {
  def unapply[T](s: Seq[T]) =
    s.headOption.map(head => (head, s.tail))
}

REPL показывает мне, что

scala> Vector[Int]() == Nil
res37: Boolean = true

... так почему я не могу использовать этот оператор case Nil для Vector?

Ответ 1

Сравнение Vector[Int]() == Nil возможно, потому что нет ограничений на уровне типа для того, что вы сравниваете; что позволяет реализовать equals для коллекций, с другой стороны, выполнить элемент путем сравнения элементов независимо от типа коллекции:

Vector(1, 2, 3) == List(1, 2, 3)  // true!

В сопоставлении с образцом вы не можете иметь случай для пустого списка (Nil), когда тип не связан с списком (это a Vector).

Вы можете сделать это, однако:

val x = Vector(1, 2, 3)

x match {
  case y +: ys => println("head: " + y + "; tail: " + ys)
  case IndexedSeq() => println("empty vector")
}

Но я бы предложил просто использовать случай по умолчанию здесь, потому что если x не имеет элемента head, он должен быть технически пустым:

x match {
  case y +: ys => println("head: " + y + "; tail: " + ys)
  case _ => println("empty vector")
}