Очевидно, что сопоставление с образцом в F # намного мощнее, чем мы используем в обычной разработке.
Во-первых, вы можете связать несколько значений одновременно. Как правило, вы будете делать это с List.partition
:
let data = [7;0;0;0;1;0;1;1;1;1;0;0;1;1;0]
let ones, others = data |> List.partition ((=) 1) // bind two values
В качестве примечания вы можете привязать несколько идентификаторов к одному значению:
let (a & b) = 42 // a = 42; b = 42
Давайте начнем с простой привязки let
для простоты.
let hd::tl = data
предупреждение FS0025 : для этого выражения найден неполный образец. Например, значение «[]» может указывать на случай, не охватываемый шаблоном (ами).
Чтобы смягчить это, мы должны добавить еще один случай для пустого списка:
let (hd::tl) | [] = data
ошибка FS0018 : две стороны этого шаблона 'или' связывают разные наборы переменных
И это правда; в случае пустого списка hd
и tl
остаются несвязанными. tl
легко связать с тем же пустым списком:
let (hd::tl) | ([] as tl) = data
Однако ошибка Ошибка FS0018 не исчезает. В самом деле, мы также должны предоставить некоторое значение по умолчанию для hd
.
Следующий подвох сделает это.
let (hd::tl, _) | ([] as tl , hd) = data, 42
Строка выше свяжет hd
с головой data
, в случае, если список не пуст, или с дополнительным значением, указанным во втором значении tuple
.
Примечание Я не нашел способа встроить 42
в конструкцию let
.
Наконец, то же самое для car
функции:
let car ((hd::tl, _) | ([] as tl, hd)) = hd
let foo = car(data, 42) // foo = 7
let bar = car([], 42) // bar = 42