Unions
A.k.a. Discriminated Unions (DU)
Points clés
Terme exacte : « Union discriminée », Discriminated Union (DU)
Types Somme : représente un OU, un choix entre plusieurs Cases
Même principe que pour une
enum
mais généralisé
Chaque case doit avoir un Tag (a.k.a Label)
C'est le discriminant de l'union pour identifier le case
Chaque case peut contenir des données
Qualification des Tags
Les Tags peuvent être utilisés :
sans qualification →
Adulte
sauf pour résoudre un conflit de noms ou par choix de nommage →
Billet.Adulte
☝ On peut forcer l'usage avec qualification en décorant l'union de l'attribut RequireQualifiedAccess
, essentiellement pour des raisons de nommage de l'union et de ses tags, pour que le code se lise sans ambiguïté.
Casse des Tags
Les Tags doivent être nommés en PascalCase ❗
💡 Depuis F# 7.0, la camelCase est possible si l'union est décorée avec RequireQualifiedAccess.
Champs nommés - Labelled Fields
Pratiques pour :
Ajouter un sens à un type primitif : → Dans l'exemple précédent, en ligne 4, le case
Enfant
contient un champ de typeint
qui est nomméage
.Distinguer deux champs du même type au sein d'un Tuple : → Exemple :
☝ Notes :
Le nommage des champs est optionnel.
En tant que champ, on optera pour le PascalCase. Mais on peut aussi les voir en tant que paramètres, alors en camelCase.
Quand un case contient plusieurs champs, on peut n'en nommer que certains. → Mais je ne recommande pas cette dissymétrie.
Déclaration
Sur plusieurs lignes : 1 ligne / case → ☝ Ligne indentée et commençant par |
Sur une seule ligne -- si déclaration reste courte ❗ → 💡 Pas besoin du 1er |
Instanciation
Tag ≃ constructeur → Fonction appelée avec les éventuelles données du case
Conflit de noms
Quand 2 unions ont des tags de même nom → Qualifier le tag avec le nom de l'union
Accès aux données internes
Uniquement via pattern matching Matching d'un type Union est exhaustif
Single-case union
Union avec un seul cas encapsulant un type (généralement primitif)
Assure type safety contrairement au simple type alias → Impossible de passer un CustomerId
à une fonction attendant un OrderId
👍
Permet d'éviter Primitive Obsession à coût minime
Style "enum"
Tous les cases sont vides = dépourvus de données → ≠ enum
.NET 📍Enums
Dernière mise à jour
Cet article vous a-t-il été utile ?