Pattern matching

Конструкция match и сопоставление паттернов

Последнее обновление: 14.12.2023

Pattern matching (сопоставление шаблонов/паттернов) представляет механизм, который позволяет сопоставить некоторое выражение с определенным шаблоном. И если сопоставление прошло успешно, то выполняются определенные действия. Для сопоставления шаблонов язык F# предоставляет конструкцию match:

match выражение with
| шаблон_1 -> выполняемые_действия_1
| шаблон_2 -> выполняемые_действия_2
| шаблон_N -> выполняемые_действия_N

После оператора match указывается сравниваемое выражение. Затем после оператора with определяются шаблоны, с которым сравнивается выражение. Перед каждым шаблон ставится вертикальная черта |:

| шаблон_1 -> выполняемые_действия_1

После шаблона через оператор -> указываются действия, которые выполняются, если выражение соответствует данному шаблону.

В итоге конструкция match просматривает по порядку шаблоны и сравнивает с ними выражение. Если найден шаблон, которому соответствует выражение, то выполняются указанные для шаблона действия. И дальше шаблоны не проверяются.

Если ни один из шаблонов не соответствует выражению, то никакие действия не выполняются.

Паттерн сопоставления констант

Существует много типов сопоставления шаблонов. И для начала возьмем самый простой - сопоставление с константами или constant pattern

Constant pattern предполагает, что выражение сравнивается с константными значениями, например, литералами - числами, строками, символами, а также со значениями перечислений:

let number = 2

match number with 
| 1 -> printfn "Number is one"
| 2 -> printfn "Number is two"
| 3 -> printfn "Number is three"

printfn "End of Program"    // инструкция после конструкции match

Здесь значение number сравнивается с рядом констант - числами 1, 2, 3. Поскольку это значение равно 2, то будет выполняться действие printfn "Number is two". И в данном случае мы получим следующий консольный вывод:

Number is two
End of Program

Не всегда имеющиеся шаблоны могут покрыть все возможные варианты значений. Например, переменная number может иметь значение, которое не соответствует ни одному из шаблонов. И если шаблон не будет найден, то мы получим ошибку во время выполнения программы. В этом случае мы можем применять универсальный шаблон _, который будет соответствовать все другим вариантам:

let number = 2

match number with 
| 1 -> printfn "Number is one"
| 2 -> printfn "Number is two"
| 3 -> printfn "Number is three"
| _ -> printfn "Undefined number"  

printfn "End of Program"    // инструкция после конструкции match

Теперь переменная number не соответствует ни одному из константых шаблонов, поэтому она будет соответствовать универсальному шаблону _. И мы получим следующий консольный вывод:

Undefined number
End of Program

Подобным образом можно сопсотавлять с константами, определенными в перечислениях:

// перечисление color с тремя константами
type Color =
    | Red = 0
    | Green = 1
    | Blue = 2

let color = Color.Red

match color with
| Color.Red -> printfn "Red"
| Color.Green -> printfn "Green"
| Color.Blue -> printfn "Blue"
| _ -> ()

Возвращение значения из match

Конструкция match может возвращать значение, которое можно присвоить или возвратить из функции:

let number = 1

let result = match number with 
             | 1 -> "Number is one"
             | 2 -> "Number is two"
             | 3 -> "Number is three"
             | _ -> "Undefined number"  

printfn "%s" result     // Number is one

Здесь в зависимости от результата конструкция match возвращает определенную строку, которая присваивается значению result. Обратите внимание, что шаблоны должны иметь то же количество отступов от начала строки, что и оператор match

Сопоставление идентификаторов

Сопоставление идентификаторов или identifier pattern позволяет сопоставить выражение с идентификатором и обычно применяется для сопоставления с вариантами дискриминированных объединений. Например:

// дискриминированное объединение
type FamilyStatus =
    | Married
    | Single
    | Complicated

let status: FamilyStatus = Married

match status with 
| Married -> printfn "женат/замужем"
| Single -> printfn "холост/не замужем"
| Complicated -> printfn "все сложно"

Здесь определено объединение FamilyStatus, которое представляет семейный статус и которое определяет три варианта. Конструкция match принимает значение этого типа - значение status и последовательно сравнивает его с возможными случаями объединения. И в зависимости от результата выводит ту или иную строку на консоль.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850