2008-10-14 12 views
47

Я пытался объяснить разницу между операторами switch и сопоставлением шаблонов (F #) с несколькими людьми, но я действительно не смог объяснить это хорошо. Почти все время они просто посмотри на меня и скажи: «Так почему бы тебе просто не использовать, если ... потом ...».Объяснение соответствия шаблонов vs switch

Как вы это объясните им?

EDIT! Спасибо всем за отличные ответы, мне очень хотелось бы отметить несколько правильных ответов.

ответ

34

Будучи одним из «тех людей», я не знаю, что есть краткий способ подвести итог тому, почему соответствие шаблонов - такая вкусная доброта. Это экспериментально.

Назад, когда я только что взглянул на сопоставление шаблонов и подумал, что это прославленный оператор switch, я думаю, что у меня не было опыта программирования с алгебраическими типами данных (кортежи и дискриминационные союзы), и он не совсем понял, что совпадение шаблонов было как контрольной конструкцией , так и связующей конструкцией. Теперь, когда я программировал F #, я, наконец, «понял». Яркость шаблона соответствия обусловлена ​​слиянием функций, имеющихся в функциональных языках программирования, и поэтому нетривиальным для ценителей посторонних.

Я попытался подвести один аспект того, почему сопоставление шаблонов полезно во второй короткой двухчастной блоге блога по языку и API-дизайну; выезд part one и part two.

+8

"experiential". Хорошее слово. :-) – 2011-02-22 09:41:52

-1

Возможно, вы могли бы провести аналогию со строками и регулярными выражениями? Вы описываете , что вы ищете, и дайте компилятору вычислить как для себя. Это делает ваш код намного проще и понятнее.

В стороне: я считаю, что самая полезная вещь в сопоставлении с образцами заключается в том, что она поощряет хорошие привычки. Я рассматриваю угловые случаи первый, и легко проверить, что я рассмотрел каждый случай.

5

Off верхней части моей головы:

  1. Компилятор может сказать, если вы не охвачены все возможности в своих матчах
  2. Вы можете использовать матч как задание
  3. Если у вас есть дискриминированный союз, в каждом матче может быть другой тип:
28

Шаблоны дают вам небольшой язык, чтобы описать структуру значений, которые вы хотите сопоставить. Структура может быть сколь угодно глубокой, и вы можете привязывать переменные к частям структурированного значения.

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

type expr = 
    | Int of int 
    | Var of string 
    | Add of expr * expr 
    | Mul of expr * expr;; 

let rec d(f, x) = 
    match f with 
    | Var y when x=y -> Int 1 
    | Int _ | Var _ -> Int 0 
    | Add(f, g) -> Add(d(f, x), d(g, x)) 
    | Mul(f, g) -> Add(Mul(f, d(g, x)), Mul(g, d(f, x)));; 

Кроме того, поскольку сопоставление с образцом является статической конструкцией для статических типов, компилятор может (я) проверить, что вы охватывали все случаи (ii) обнаруживали избыточные ветви, которые никогда не могут соответствовать какой-либо ценности (iii) обеспечивают очень эффективную реализацию (с прыжками и т. д.).

+0

Хороший пример. Объясняя соответствие шаблону «нефункциональным людям», я хотел бы упомянуть, что с PM ваше состояние может проверить «форму» ваших данных, что намного сложнее, уродливо и неэффективно с помощью if/switch. – 2010-12-09 07:50:20

+0

`Добавить expr * expr` Я думаю, вы хотели написать` + ` – 2013-01-26 02:42:29

4

Переключатель - это два передних колеса.

Образец соответствия - это весь автомобиль.

13

Отрывок из this blog article:

шаблона соответствие имеет ряд преимуществ по сравнению отчетности коммутаторов и способ отправки:

  • шаблона спичек может действовать на Интс, поплавков, струнные и других типов, также объекты.
  • Сопряжения по образцу могут воздействовать на несколько различных значений одновременно: Параллельный образец соответствия. Способ Отправка и переключатель ограничены одним значением , например. "это".
  • Образцы могут быть вложенными, позволяя Отправка над деревьями произвольных глубина. Метод отправки и переключения ограничен не вложенным корпусом.
  • Or-patterns позволяют подшаблонам быть совместно. Метод отправки разрешает только обмен , когда методы начинаются с классов, которые разделяют базу . В противном случае вы должны вручную указать фактору общности в отдельную функцию (давая ей имя ), а затем вручную вставьте вызовы из всех соответствующих мест в ненужную функцию .
  • Соответствие шаблону обеспечивает избыточность Проверка, которая улавливает ошибки.
  • Вложенные и/или параллельные шаблоны матчи оптимизированы для вас компилятором F # . OO эквивалент должен быть написаны вручную и постоянно reoptimized вручную во время развития, что является чрезмерно утомительно и чревато ошибками, так производственного качества OO код, как правило быть очень медленным в сравнении.
  • Активные шаблоны позволяют ввести выборочную семантику отправки.
3

Образцы шаблонов в OCaml, помимо того, что они более выразительны, как упомянуто несколькими способами, описанными выше, также дают некоторые очень важные статические гарантии. Компилятор будет доказать вам, что дело-анализ воплощен в выписке шаблона матча:

  • исчерпывающие (ни одного случая не пропустил)
  • без избыточности (нет случаев, которые никогда не могут быть поражены, потому что они Вытеснено в предыдущем случае)
  • звук (нет моделей, которые невозможно данный тип данных в вопросе)

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

5

Кортежи имеют «,» и варианты имеют Ctor args ..это конструкторы, они создают вещи.

Образцы являются деструкторами, они разрывают их на части.

Это двойные понятия.

Чтобы сделать это более убедительно: понятие кортежа или варианта не может быть описано просто его конструктором: требуется деструктор или сделанное вами значение бесполезно. Именно эти двойные описания определяют значение.

Как правило, мы рассматриваем конструкторы как данные, а деструкторы - как поток управления. Деструкторы вариантов - это альтернативные ветви (один из многих), деструкторы кортежей - параллельные потоки (все из них).

параллелизм проявляется в операциях как

(f * g) . (h * k) = (f . h * g . k) 

если вы думаете управления, протекающего через функцию, кортежи обеспечивают способ разделить вычисление на параллельные нити управления.

Посмотрите, таким образом, выражения - это способы составления кортежей и вариантов для создания сложных структур данных (подумайте об AST).

И шаблонные матчи - это способы составления деструкторов (опять же, подумайте об АСТ).

0

Операторы If-Else (или switch) о выборе различных способов обработки значения (ввода) в зависимости от свойств от стоимости.

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

Таким образом, сопоставление шаблонов является скорее деконструкцией значений, чем выбором, это делает их очень удобным механизмом для определения (рекурсивных) функций на индуктивных структурах (рекурсивных типах объединения), что объясняет, почему они настолько обильно используются на таких языках, как Ocaml и т. д.

PS: Возможно, вы знаете шаблоны соответствия и If-Else «шаблоны» из их ad-hoc использования в математике;

"если х обладает свойством А, то у другого г" (If-Else)

"некоторый срок в p1..pn где .... это простое разложение х .." ((единичный случай))