Паттерны кортежей позволяют сравнивать значения кортежей. Например, передадим в конструкцию match кортеж с названием языка и времени дня и в зависимости от переданных данных возвратим определенное сообщение:
let getMessage settings = match settings with | ("english", "morning") -> "Good morning" | ("english", "evening") -> "Good evening" | ("russian", "morning") -> "Доброе утро" | ("russian", "evening") -> "Добрый вечер" | _ -> "" printfn "%s" (getMessage ("english", "morning")) // Good morning printfn "%s" (getMessage ("russian", "evening")) // Добрый вечер
Здесь в функцию getMessage передается параметр settings. Если это кортеж с двумя элементами ("english", "morning"), то возвращаем строку "Good morning". Для других значений кортежа возвращаем другое сообщение.
Если какие-то элементы кортежа не имеют значения, и мы хотим исключить их значение из сопоставления, то вместо подобных элементов указывается прочерк:
let getMessage settings = match settings with | ("english", _) -> "Hello" | ("russian", _) -> "Привет" | _ -> "" printfn "%s" (getMessage ("english", "morning")) // Hello printfn "%s" (getMessage ("russian", "evening")) // Привет
В данном случае второй элемент кортежа не важен, и сравниваем только первый элемент двухэлементного кортежа. Однако сравниваемый кортеж по прежнему должен иметь два элемента.
Паттерн переменных позволяет разложить кортеж на отдельные переменные. Например:
let printPerson person = match person with | (name, age, "Microsoft") -> printfn $"{name} ({age}) - Microsoft" | (name, age, _) -> printfn $"{name} ({age})" | _ -> () printPerson ("Tom", 39, "Microsoft") // Tom (39) - Microsoft printPerson ("Bob", 43, "Google") // Bob (43) printPerson ("Sam", 28, "Jetbrains") // Sam (28)
Здесь в функцию printPerson передается кортеж из трех элементов, который содержит имя, возраст и компанию пользователя. В конструкции match первый паттерн предполагает, что третий элемент кортежа будет представлять строку "Microsoft", а первые два элемента передаются в переменные name и age.
(name, age, "Microsoft") -> printfn $"{name} ({age}) - Microsoft"
Во втором паттерне также определяются те же переменные, только значение третьего элемента не важно.
Паттерн типов record позволяет разложить значения record на отдельные переменные. Например:
type Person = { Name: string; Language: string } let printHello person = match person with | { Name = username; Language = "russian"; } -> printfn "Привет, %s" username | { Name = username; Language = "english"; } -> printfn "Hello, %s" username | _ -> printfn "你好" let tom = {Name="Tom"; Language="russian"} let bob = {Name="Bob"; Language="english"} let sam = {Name="Sam"; Language="german"} printHello tom // Привет, Tom printHello bob // Hello, Bob printHello sam // 你好
Здесь определена запись Person, которая состоит из двух свойств - Name (имя пользователя) и Language (язык пользователя)
В функции printHello получаем объект Person и разлагаем на отдельные значения. Например, если у пользователя указан русский язык, то объект Person сопоставляется со следующим шаблоном:
{ Name = username; Language = "russian"; } -> printfn "Привет, %s" username
В данном случае получаем имя пользователя в переменную username и используем ее при выводе сообщения на экран.