Lors de la définition d'un type d'union, vous répertoriez toutes les manières de construire une valeur de ce type. Dans sa forme la plus simple, cette définition ressemble à ceci:
type Visibility
= All
| Active
| Completed
Comme vous l'avez deviné, ce type Visibility
déclare et définit trois valeurs, tous de type Visibility
. La seule façon de construire une valeur de type Visibility
consiste à utiliser l'une de ces trois options. Pour cette raison, nous les appelons souvent «constructeurs».
Voici une définition de type union un peu plus compliqué:
type TrainStatus
= OnTime
| Delayed Int
Comme on peut s'y attendre, cela définit deux nouveaux "constructeurs" OnTime
et Delayed
. Mais regardez leurs types:
OnTime : TrainStatus
Delayed : Int -> TrainStatus
Le constructeur OnTime
prend zéro arguments, et est donc simplement une valeur; c'est déjà un TrainStatus
. Mais Delayed
est déclaré en tant que constructeur à un argument: c'est une fonction qui crée un nouveau TrainStatus
sur un Int
. En tant que tels, Delayed 5
, Delayed 10
et Delayed 100
sont toutes des valeurs TrainStatus
valides. (Nous pouvons les interpréter comme "retardé de 5 minutes" ou quelque chose de similaire.
Un constructeur peut prendre plusieurs arguments; par exemple, si nous aimerions inclure, en tant que chaîne, une raison d'un retard:
type TrainStatus
= OnTime
| Delayed Int String
ts : TrainStatus
ts = Delayed 20 "The conductor took a short nap."
qui définit Delayed : Int -> String -> TrainStatus
.
Si vous êtes donné un TrainStatus
, vous pouvez extraire le Int
et String
à l'intérieur de celui-ci en utilisant la correspondance de motif:
case ts of
OnTime ->
"Your train is on time!"
Delayed minutes reason ->
"Your train has been delayed by " ++ toString minutes ++ " because " ++ reason