Scala est un langage à l'appui de disjonctions dans la correspondance de motif ("Pattern Alternatives'):
x match {
case _: String | _: Int =>
case _ =>
}
Cependant, j'ai souvent besoin de déclencher une action si le scrutinee satisfait PatternA et PatternB (conjonction.)
J'ai créé un modèle de combinateur '&&' qui ajoute cette fonctionnalité. Trois petites lignes qui vraiment me rappellent pourquoi j'aime la Scala!
// Splitter to apply two pattern matches on the same scrutinee.
object && {
def unapply[A](a: A) = Some((a, a))
}
// Extractor object matching first character.
object StartsWith {
def unapply(s: String) = s.headOption
}
// Extractor object matching last character.
object EndsWith {
def unapply(s: String) = s.reverse.headOption
}
// Extractor object matching length.
object Length {
def unapply(s: String) = Some(s.length)
}
"foo" match {
case StartsWith('f') && EndsWith('f') => "f.*f"
case StartsWith('f') && EndsWith(e) && Length(3) if "aeiou".contains(e) => "f..[aeiou]"
case _ => "_"
}
Points de discussion
- Est-il un moyen de faire cela?
- Sont-il des problèmes avec cette approche?
- Existe-il d'autres utiles combinators qui pourraient être créés avec cette approche? (par exemple,
Not
) - Si une telle combinator être ajouté à la bibliothèque standard?
Mise à JOUR
J'ai juste demandé comment le compilateur interprète case A && B && C
. Ce sont des opérateur infixe modèles (Section 8.1.9 de la Scala de Référence). Vous pouvez également exprimer cette normale extraire des motifs (8.1.7) &&(&&(A, B), C)
. Remarquez comment les expressions sont associés de gauche à droite, comme la normale opérateur infixe les appels de méthode comme Boolean#&&
en val b = true && false && true
.