match: основы сопоставления
Сопоставление с образцом — это switch на стероидах: разбор значений по структуре с гарантией полноты.
match — выражение, которое сравнивает значение с набором образцов и возвращает результат первой подошедшей ветки.
От if к match
Цепочки if/elif/else быстро становятся громоздкими. match выражает «в зависимости от формы значения» компактнее и нагляднее.
let describe n =
match n with
| 0 -> "ноль"
| 1 -> "один"
| _ -> "много"
printfn "%s" (describe 0)
printfn "%s" (describe 5)Вывод:
ноль много
Каждая ветка — | образец -> результат. Подчёркивание _ — «любое другое значение» (wildcard), обязательная «ловушка» для остального.
match — это выражение
Важнейшее отличие от switch в C#: match возвращает значение, его результат можно присвоить или вернуть из функции. Все ветки обязаны давать значение одного типа.
let sign x =
match x with
| n when n > 0 -> "положительное"
| 0 -> "ноль"
| _ -> "отрицательное"
printfn "%s" (sign -3)Вывод:
отрицательное
Здесь же видно охранное условие when: ветка срабатывает, только если выражение после when истинно.
Исчерпывающность
Компилятор F# проверяет, что образцы покрывают все возможные значения. Если забыть случай, он выдаст предупреждение «Incomplete pattern matches». Это спасает от пропущенных вариантов — особенно ценно для размеченных объединений (об этом дальше).
let onlyTrue b =
match b with
| true -> "да"
// предупреждение: не покрыт случай falseНесколько образцов в ветке
Объединять варианты можно через | внутри ветки.
let isWeekend day =
match day with
| "сб" | "вс" -> true
| _ -> false
printfn "%b" (isWeekend "сб")Вывод:
true
Как работает под капотом
Компилятор превращает match в дерево решений: эффективную последовательность проверок, а не наивный перебор всех веток подряд. Для размеченных объединений это проверка тега, для констант — таблица переходов. Анализ исчерпывающности — отдельный статический проход: компилятор моделирует пространство значений и ищет непокрытые случаи.
Частые ошибки
- Забыть ветку
_и получить предупреждение о неполноте — игнорировать его опасно. - Делать ветки разного типа результата — все ветки должны возвращать один тип.
- Ставить
when-ветку после общей_— до неё не дойдёт, важен порядок.
Итоги
matchсравнивает значение с образцами и возвращает результат подошедшей ветки.- Это выражение: результат можно присвоить и вернуть; ветки одного типа.
_— wildcard,when— охранное условие,|— объединение образцов.- Компилятор проверяет исчерпывающность образцов.