Дискриміноване обʼєднання - це тип, який представляє фіксовану кількість іменованих варіантів. Кожне значення дискримінованого обʼєднання відповідає рівно одному з іменованих варіантів. Такий тип даних відомий як тип-сума.
Кожен варіант дискримінованого обʼєднання може необовʼязково мати повʼязані з ним дані, і різні варіанти можуть мати дані різних типів. Якщо жоден із варіантів не має повʼязаних із ним даних, дискриміноване обʼєднання подібне до того, що в інших мовах зазвичай називають переліченням (або enum).
Дискриміноване обʼєднання визначають за допомогою ключового слова type, і для цього потрібно зовсім небагато синтаксису. Тож ними легко користуватися, і ми зустрічаємо їх у багатьох місцях, зокрема в базовій бібліотеці.
// 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
Створити значення для конкретного варіанта можна, звернувшись до його назви або до повної назви, якщо назва не унікальна. Оскільки назви варіантів - це просто функції-конструктори, повʼязані дані можна передати як звичайний аргумент функції.
let byName = Integer 2
let byFullName = Number.Invalid
Дискриміновані обʼєднання мають структурну рівність, тобто два значення для одного й того самого варіанта з однаковими (необовʼязковими) даними є еквівалентними.
Найкращий спосіб працювати з дискримінованими обʼєднаннями - це зіставлення зі зразком за допомогою зразка ідентифікатора:
let describe number =
match number with
| Integer i -> sprintf "Integer: %d" i
| Float d -> sprintf "Float: %f" d
| Invalid -> "Invalid"