Понимание сопоставления с образцом с оператором недостатков

В "Программировании F#" я столкнулся с сопоставлением с образцом как этот (я упростил немного):

let rec len list = 
  match list with
  | [] -> 0
  | [_] -> 1
  | head :: tail -> 1 + len tail;;

Практически, я понимаю, что последнее соответствие распознает голову и хвост списка. Концептуально, я не добираюсь, почему это работает. Насколько я понимаю:: оператор недостатков, который добавляет значение в положении головы списка, но это не смотрит на меня как он, используется в качестве оператора здесь. Если я понимаю это как "специальный синтаксис" для списков, где:: интерпретируется как оператор или "шаблон соответствия" в зависимости от контекста? Или та же идея может быть расширена для типов кроме списков с другими операторами?

11
задан Mathias 17 May 2010 в 04:01
поделиться

3 ответа

В дополнение к ответу Брайана, есть несколько моментов, которые стоит отметить. Синтаксис h::t может использоваться и как оператор и как шаблон:

let l = 1::2::[]                    // As an operator
match l with x::xs -> 1 | [] -> 0   // As a pattern

Это означает, что это немного специальная конструкция, потому что другие операторы (например, +) не могут использоваться как шаблоны (для разложения результата обратно на аргументы оператора) - очевидно, что для + это было бы неоднозначно.

Также интересен паттерн [_], поскольку он является примером вложенного паттерна. Он состоит из:

  • _ - шаблон Underscore, который соответствует любому значению и не связывает никаких символов
  • [ <шаблон> ] - шаблон одноэлементного списка, который соответствует списку с одиночными элементами и соответствует элементу списка с вложенным <шаблоном>.

Вы также можете написать match 1::[] с | [x] -> x, который вернет значение единственного элемента (в данном случае 1).

10
ответ дан 3 December 2019 в 04:12
поделиться

Он используется как средство форматирования или формально шаблон , «список» сопоставляется с тремя шаблонами:

[] означает, что список пуст

[_] означает, что в списке один элемент, так как вам все равно, что это за элемент, поэтому просто поместите туда _, вы также можете использовать [a].

head :: tail означает, что список действительно состоит из двух частей: головы и хвоста.

Вы можете рассматривать сопоставление с образцом F # как мощную структуру if then else.

2
ответ дан 3 December 2019 в 04:12
поделиться

Это специальный синтаксис для списков. Вы можете представить тип list как дискриминированное объединение следующим образом:

type list<'T> =         // '
    | Nil
    | Cons of 'T * list<'T>

за исключением того, что существует специальный синтаксис, который заставляет Nil быть [] и Cons(h,t) быть h::t. Тогда это просто обычное сопоставление с образцом на дискриминированном объединении. Помогло?

(Возможно, см. также эту запись в блоге.)

.
13
ответ дан 3 December 2019 в 04:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: