Patterns
Généralités
Patterns = règles pour détecter la structure de données en entrée
Utilisés abondamment en F♯
Dans match expression, let binding de valeurs et de paramètres de fonctions
Très pratiques pour manipuler les types algébriques F♯ (tuple, record, union)
Composables : supporte plusieurs niveaux d'imbrication
Assemblables par ET/OU logiques
Supporte les littéraux :
1.0,"test"...
Wildcard Pattern
Représenté par _, seul ou combiné avec un autre pattern
Toujours vrai → A placer en dernier dans une match expression
⚠️ Toujours chercher en 1er à traiter exhaustivement/explicitement tous les cas
Quand impossible, utiliser alors le _
match option with
| Some 1 -> ...
| _ -> ... // ⚠️ Non exhaustif
match option with
| Some 1 -> ...
| Some _ | None -> ... // 👌 \+ exhaustifConstant Pattern
Détecte constantes, null et littéraux de nombre, char, string, enum
☝ Notes :
Le pattern de
Threeest aussi classé en tant que Identifier Pattern 📍Pour le matching de
null, on parle aussi de Null Pattern
Identifier Pattern
Détecte les cases d'un type union ainsi que leur éventuel contenu
Variable Pattern
Assigne la valeur détectée à une "variable" pour l'utiliser ensuite
Exemple : variables firstName et lastName ci-dessous
⚠️ On ne peut pas lier à plusieurs reprises vers la même variable
Solutions : utiliser 2 variables puis vérifier l'égalité
Champs nommés de cases d'union
Plusieurs possibilités :
Pattern "anonyme" du tuple complet → Il faut déconstruire tous les champs du tuple. → On utilise la virgule
,pour séparer ces champs.Pattern d'un seul champ par son nom →
Field = valuePattern de plusieurs champs par leur nom →
F1 = v1; F2 = v2⚠️ Ne pas confondre avec l'option 1 : → Le délimiteur est ici le point-virgule;et non la virgule,!
Alias Pattern
as permet de nommer un élément dont le contenu est déconstruit
💡 Marche aussi dans les fonctions :
OR et AND Patterns
Permettent de combiner deux patterns (nommés P1 et P2 ci-après)
P1 | P2→ P1 ou P2. Ex :Rectangle (0, _) | Rectangle (_, 0)P1 & P2→ P1 et P2. Utilisé surtout avec 🚀 Active Patterns📍
💡 On peut utiliser la même variable (name ci-dessous) dans 2 patterns :
Parenthesized Pattern
Usage des parenthèses () pour grouper des patterns, pour gérer la précédence
☝ Note : la ligne ① ne compilerait sans faire () :: tail
⚠️ Les parenthèses compliquent la lecture
💡 Essayer de s'en passer quand c'est possible
Construction Patterns
Reprennent syntaxe de construction d'un type pour le déconstruire
Cons et List Patterns
Array Pattern
Tuple Pattern
Record Pattern
Cons et List Patterns
≃ Inverses de 2 types de construction d'une liste, avec même syntaxe
Cons Pattern : head :: tail → décompose une liste (avec >= 1 élément) en :
Head : 1er élément
Tail : autre liste avec le reste des éléments - peut être vide
List Pattern : [items] → décompose une liste en 0..N éléments
[]: liste vide[x]: liste avec 1 élément mis dans la variablex[x; y]: liste avec 2 éléments mis dans les variablesxety[_; _]: liste avec 2 éléments ignorés
💡 x :: [] ≡ [x], x :: y :: [] ≡ [x; y]...
La match expression par défaut combine les 2 patterns : → Une liste est soit vide [], soit composée d'un item et du reste : head :: tail
Les fonctions récursives parcourant une liste utilise le pattern [] pour stopper la récursion :
Array Pattern
Syntaxe: [| items |] pour 0..N items entre ;
☝ Il n'existe pas de pattern pour les séquences, vu qu'elles sont "lazy".
Tuple Pattern
Syntaxe : items ou (items) pour 2..N items entre ,
💡 Pratique pour pattern matcher plusieurs valeurs en même temps
Record Pattern
Syntaxe : { Fields } pour 1..N Field = variable entre ;
Pas obligé de spécifier tous les champs du Record
En cas d'ambiguïté, qualifier le champ :
Record.Field
💡 Marche aussi pour les paramètres d'une fonction :
⚠️ Rappel : il n'y a pas de pattern pour les Records anonymes !
Type Test Pattern
Syntaxe : my-object :? sub-type
Renvoie un bool
→ is C♯ (my-object is sub-type)
Usage : avec une hiérarchie de types
☝️ Remarque : l'opérateur :? n'est pas conçu pour vérifier des évidences car il adopte alors un comportement déroutant :
(Exemple tiré de cette question stackoverflow)
Bloc try/with
try/withOn rencontre fréquemment ce pattern dans les blocs try/with :
Boxing
Le Type Test Pattern ne marche qu'avec des types références.
→ Pour un type valeur ou inconnu, il faut le convertir en objet (a.k.a boxing)
Last updated
Was this helpful?