2011-07-18 5 views
8

Je voudrais qu'un extracteur convertisse implicitement ses paramètres, mais cela ne semble pas fonctionner. Considérez ce cas très simple:Scala - conversion implicite avec unapply

case class MyString(s: String) {} 

implicit def string2mystring(x: String): MyString = new MyString(x) 
implicit def mystring2string(x: MyString) = x.s 

object Apply { 
    def unapply(s: MyString): Option[String] = Some(s) 
} 

Mais je ne suis pas en mesure de l'utiliser comme j'attendre:

val Apply(z) = "a" // error: scrutinee is incompatible with pattern type 

Quelqu'un peut-il expliquer pourquoi il ne parvient pas à convertir le paramètre String-MyString? Je m'attendrais à appeler le string2mystring("a") à la volée. Clairement je pourrais contourner le problème en disant val Apply(y) = MyString("a"), mais il ne semble pas que je devrais faire cela.

Remarque: Cette question est similaire à this one, mais 1) que l'on n'a pas vraiment de bonne réponse pour expliquer pourquoi cela se produit, 2) l'exemple est plus complexe qu'il ne devrait l'être.

Répondre

14

Les conversions implicites ne sont pas appliquées lors de la correspondance de modèle. Ce n'est pas un bug ou un problème avec votre code, c'est simplement une décision de conception des créateurs de Scala. Pour corriger cela, vous devez écrire un autre extracteur qui accepte un String - qui à son tour peut appeler votre conversion implicite.

Vous pouvez essayer avec une vue liée, ce qui semble fonctionner aussi bien, et travaillerez également si vous définissez plus tard d'autres conversions implicites à MyString:

object Apply { 
    def unapply[S <% MyString](s: S): Option[String] = Some(s.s) 
} 
+1

Merci. C'est un peu décevant. Savez-vous quelle est la motivation de cette décision? – dhg

+0

Oui, en ajoutant 'def unapply (p: String): Option [String] = Some (p)' à 'Apply' fait l'affaire. Donc, je vais aller avec ça. Merci. – dhg

+0

@dhg J'ai édité la réponse - une vue liée semble fonctionner aussi bien. –

Questions connexes