O tipo união discriminada representa um número fixo de casos nomeados. Cada valor de uma união discriminada corresponde a exatamente um dos casos nomeados. Esse tipo de dado é conhecido como tipo soma.
Cada caso de uma união discriminada pode ter, opcionalmente, dados associados, e casos diferentes podem ter tipos de dados diferentes. Se nenhum dos casos tiver dados associados, a união discriminada é parecida com o que outras linguagens costumam chamar de enumeração (ou enum).
Uma união discriminada é definida com a palavra-chave type e exige muito pouca sintaxe. Isso as torna fáceis de usar, e você vai encontrá-las em muitos lugares, inclusive na biblioteca base.
// Discriminated union without associated data
type Season =
| Spring
| Summer
| Autumn
| Winter
// Discriminated union with associated data
type Number =
| Integer of int
| Float of float
| Invalid
Você pode criar um valor para um caso específico referindo-se ao nome dele ou ao nome completo, caso o nome não seja único. Como os nomes dos casos são apenas funções construtoras, os dados associados podem ser passados como um argumento de função comum.
let byName = Integer 2
let byFullName = Number.Invalid
As uniões discriminadas têm igualdade estrutural, o que significa que dois valores do mesmo caso e com os mesmos dados (opcionais) são equivalentes.
A forma preferida de trabalhar com uniões discriminadas é por meio de correspondência de padrões usando o padrão de identificador:
let describe number =
match number with
| Integer i -> sprintf "Integer: %d" i
| Float d -> sprintf "Float: %f" d
| Invalid -> "Invalid"