Тип «розрізнюване обʼєднання» представляє фіксовану кількість іменованих варіантів. Кожне значення розрізнюваного обʼєднання відповідає рівно одному з іменованих варіантів.
Розрізнюване обʼєднання визначають за допомогою ключового слова type, а його варіанти розділяють символами вертикальної риски (|):
type Season =
| Spring
| Summer
| Autumn
| Winter
Кожен варіант розрізнюваного обʼєднання може необовʼязково мати повʼязані з ним дані, і різні варіанти можуть мати різні типи даних. Якщо з жодним із варіантів не повʼязано даних, розрізнюване обʼєднання подібне до того, що в інших мовах зазвичай називають переліком (або enum).
type Number =
| Integer of int
| Float of float
| Invalid
Створити значення для конкретного варіанта можна, звернувшись до його назви (наприклад, Success). Оскільки назви варіантів - це просто функції-конструктори, повʼязані дані можна передати як звичайний аргумент функції. Якщо в іншому розрізнюваному обʼєднанні визначено варіант із такою самою назвою, доведеться використати його повну назву (наприклад, Result.Success).
let byName = Integer 2
let byFullName = Number.Invalid
Розрізнювані обʼєднання мають структурну рівність, тобто два значення одного й того самого варіанта з однаковими (необовʼязковими) даними є рівнозначними.
Хоча для роботи з розрізнюваними обʼєднаннями можна використовувати вирази if/elif/else, рекомендований спосіб роботи з ними - це зіставлення зі зразком за допомогою зразка-ідентифікатора:
let describe number =
match number with
| Integer i -> sprintf "Integer: %d" i
| Float d -> sprintf "Float: %f" d
| Invalid -> "Invalid"
У цій вправі День Валентина, і ми з партнером плануємо разом зробити щось приємне. У партнера багато ідей, і тепер він просить нас оцінити їх, щоб вибрати, чим зайнятися.
Партнер пропонує такі ідеї:
На нас чекає шість завдань, які допоможуть обрати заняття на День Валентина.
На кожну ідею партнера ми відповідаємо однією з трьох відповідей: так, ні або можливо.
Визначте розрізнюване обʼєднання Approval, яке представляє ці відповіді трьома варіантами: Yes, No і Maybe.
Партнер обрав два можливі ресторани: один із корейською кухнею, а другий із турецькою.
Визначте розрізнюване обʼєднання Cuisine, яке представляє ці кухні двома варіантами: Korean і Turkish.
Фільмів на вибір безліч, тож щоб звузити коло, партнер також перелічує їхні жанри.
Визначте розрізнюване обʼєднання Genre, яке представляє такі жанри варіантами: Crime, Horror, Romance і Thriller.
Як уже згадувалося, партнер придумав пʼять різних занять: гра в настільну гру, розслабитися, подивитися фільм, піти до ресторану й прогулятися.
Визначте розрізнюване обʼєднання Activity, яке представляє ці типи занять:
BoardGame: без повʼязаних даних.Chill: без повʼязаних даних.Movie: має Genre як повʼязані дані.Restaurant: має Cuisine як повʼязані дані.Walk: має int, що позначає кількість кілометрів для прогулянки, як повʼязані дані.Нарешті ми готові оцінити ідеї партнера. Ось як ми ставимося до кожної з них:
Реалізуйте функцію з назвою rateActivity, яка приймає значення Activity і повертає Approval на основі наведених вище відчуттів:
rateActivity (Restaurant Turkish)
// => Maybe
Зареєструйтеся на Exercism, щоб вивчати й опановувати F#, а також 18 концепцій148 вправ та справжнє наставництво від людей, і все це безкоштовно.