2009-04-11 10 views
2

EDIT: Ce fut un vieux bug depuis longtemps fixé à Scala 2.8 et plus tardPourquoi la chaîne vide ne correspond-elle pas à Seq.empty?

Au cours de l'expérimentation autour de la question Pattern matching a String as Seq[Char], je suis tombé sur un autre phénomène correspondant bizarre. Considérez le code suivant qui traite une chaîne comme une séquence de caractères:

def %%&#(input: String) : String = { 
    val uha : Seq[Char] = input 
    uha match { 
     case Seq() => "Empty" 
     case Seq(first @ _, 'o', 'o') => "Bar" 
     case _ => "Oh" 
    } 
} 

entrée d'appel sur la chaîne vide "" cède correctement "Empty".

Cependant, si je réécris la première clause de match

case Seq.empty => "Empty" 

l'appariement des "" échoue et correspond à la clause par défaut à la place. Marcher à travers le code source de la bibliothèque Scala (que vous ne devriez pas avoir à faire dans un monde idéal :-)) Je crois que les deux Seq() et Seq.empty donneront RandomAccessSeq.empty. Apparemment, cela ne concorde pas avec le phénomène décrit ci-dessus parce que seulement Seq() correspond à la chaîne vide.

MISE À JOUR: Après une expérimentation plus loin cette question peut être réduite à ce qui suit:

val list = List() 
    >>> list2: List[Nothing] = List() 
val emptySeq = Seq.empty 
list == emptySeq 
    >>> res1: Boolean = false 

Cela signifie essentiellement qu'un Seq vide ne est pas automatiquement égale Seq.empty. Donc, en cas de correspondance avec une constante (par opposition à l'utilisation d'un extracteur comme suggéré par starblue), cette inégalité conduit à l'échec de la correspondance. La même chose est vraie lors de l'interprétation du String vide en tant que séquence.

+1

Apparemment, cela sera résolu dans Scala 2.8. Dans l'attente de cela. –

+0

Bon cas, mais maintenant expiré depuis que le bug est corrigé (peut-être déjà il y a des années). Quelle est la politique de Stackoverflow pour les mettre en pause afin qu'il n'apparaisse pas dans les recherches? – akauppi

+0

Pourriez-vous s'il vous plaît marquer en quelque sorte que cela s'applique à Scala <2.8 seulement (c'est dans le commentaire mais nous ne commençons pas à lire là). Meta a une discussion ouverte sur ce qu'il faut faire avec les problèmes. ceci: http://meta.stackoverflow.com/questions/252520/mark-questions-or-answers-as-out-of-date – akauppi

Répondre

4

Cela semble être un bogue dans la bibliothèque. Voulez-vous déposer le bug ou dois-je?

scala> Seq.empty match {case Seq() => "yup"; case _ => "nope"} 
res0: java.lang.String = yup 

scala> Seq() match {case Seq.empty => "yup"; case _ => "nope"} 
res1: java.lang.String = yup 

scala> ("" : Seq[Char]) match {case Seq() => "yup"; case _ => "nope"}  
res2: java.lang.String = yup 

scala> ("" : Seq[Char]) match {case Seq.empty => "yup"; case _ => "nope"} 
res3: java.lang.String = nope 
+0

Donc le bug est vraiment ce genre de sous-types de Seq [A] tels que List et RichString ne sont pas égaux à Seq.empty quand ils sont construits (avec List() resp. ("": Seq [Char])), alors que d'autres tels que RandomAccessSeq le sont. Cela pourrait-il être intentionnel pour une raison quelconque? –

0

En faisant correspondre les fonctions nonappliquées ou non utiliséesSeq sont utilisées, ne pas appliquer comme vous semblez le croire.

Questions connexes