Понимание соответствия шаблонов с операторами cons
В "Программирование F #" я столкнулся с подобранным шаблоном (я немного упростил):
let rec len list =
match list with
| [] -> 0
| [_] -> 1
| head :: tail -> 1 + len tail;;
Практически я понимаю, что в последнем матче распознается голова и хвост списка. Понятно, что я не понимаю, почему это работает. Насколько я понимаю,:: - это оператор cons, который добавляет значение в головную позицию списка, но мне не кажется, что он используется в качестве оператора здесь. Должен ли я понимать это как "специальный синтаксис" для списков, где:: интерпретируется как оператор или "шаблон соответствия" в зависимости от контекста? Или может ли распространяться та же идея для типов, отличных от списков, с другими операторами?
Ответы
Ответ 1
В дополнение к ответу Брайана, есть несколько моментов, которые стоит отметить. Синтаксис h::t
может использоваться как оператор, так и как шаблон:
let l = 1::2::[] // As an operator
match l with x::xs -> 1 | [] -> 0 // As a pattern
Это означает, что это немного специальная конструкция, потому что другие операторы (например, +
) не могут использоваться в качестве шаблонов (для разложения результата обратно на аргументы оператора) - очевидно, для +
это будет двусмысленным.
Также интересен шаблон [_]
, потому что это пример вложенного шаблона. Он состоит из:
-
_
- шаблон подчеркивания, который соответствует любому значению и не привязывает никакие символы
-
[ <pattern> ]
- шаблон элемента с одним элементом, который соответствует спискам с отдельными элементами и соответствует элементу списка с вложенным <pattern>
.
Вы также можете написать match 1::[] with | [x] -> x
, который вернет значение одного элемента (в этом случае 1).
Ответ 2
Это особый синтаксис для списков. Вы можете представить тип list
как дискриминационный союз:
type list<'T> = // '
| Nil
| Cons of 'T * list<'T>
за исключением того, что существует специальный синтаксис, который делает Nil
be []
и Cons(h,t)
be h::t
. Тогда это просто нормальное соответствие шаблонов на дискриминационном объединении. Помогает ли это?
(Возможно, также смотрите эту запись в блоге.)
Ответ 3
Он используется как форматер или формально pattern
, `list 'сопоставляется с тремя шаблонами:
[] означает, что список пуст.
[_] означает, что список имеет один элемент, так как вас не волнует, что такое элемент, поэтому просто добавьте _ там, вы также можете использовать [a].
head:: tail означает, что список имеет две части: головку и хвост.
Вы можете просмотреть сопоставление шаблонов F # в качестве мощной структуры if if else.