Je ne trouve rien dans la spécification du langage concernant les clauses de correspondance inatteignables. Quelqu'un me corrige si je me trompe.
Je suppose donc que les erreurs de compilation inatteignables sont faites sur la base d'un maximum d'efforts, ce qui pourrait expliquer pourquoi le premier cas ne se plaint pas.
scala -Xprint:typer
suggère que Nil
est un schéma littéral utilisant immutable.this.Nil.==
pour vérifier une correspondance, tandis que List()
est un schéma d'extracteur. En regardant la mise en œuvre de l'extracteur, il semble faire quelque chose comme cela:
def unapplySeq[A](x: CC[A]): Some[CC[A]] = Some(x)
Je suis donc devenu curieux et j'ai déployé une implémentation alternative :
object ListAlt {
def unapplySeq[A](l: List[A]): Some[List[A]] = Some(l)
}
Cela fonctionne comme List()
:
scala> Nil match { case ListAlt() => 1 }
res0: Int = 1
Mais si j'implémente votre fonction avec ça, ça compile bien (à l'exception de l'avertissement non vérifié) :
def f(a: Any) = a match { case ListAlt() => 1 case Nil => 2 case _ => 0 }
scala> f(List())
res2: Int = 1
scala> f(Nil)
res3: Int = 1
scala> f(4)
res4: Int = 0
Je me demande donc si l'implémentation du moteur de correspondance de schémas traite de manière spéciale Nil
et List()
. Peut-être qu'il traite List() comme un littéral...