Объяснение соответствия шаблону vs switch

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

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

ИЗМЕНИТЬ! Спасибо всем за отличные ответы, мне очень хотелось бы отметить несколько правильных ответов.

Ответы

Ответ 1

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

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

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

Ответ 2

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

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

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)));;

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

Ответ 3

Выдержка из этой статьи в блоге:

Согласование шаблонов имеет несколько преимуществ перед операторами switch и отправкой методов:

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

Ответ 4

Сверху моей головы:

  • Компилятор может определить, не включили ли вы все возможности в своих матчах
  • Вы можете использовать совпадение как назначение
  • Если у вас есть дискриминационный союз, каждое совпадение может иметь другой тип '

Ответ 5

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

Шаблоны - это деструкторы, они разделяют их на части.

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

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

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

parallelism проявляется в таких операциях, как

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

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

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

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

Ответ 6

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

Совместимость шаблонов - это весь автомобиль.

Ответ 7

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

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

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

Ответ 8

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

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

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

PS: вы можете узнать шаблоны соответствия и If-Else "шаблоны" из своего специального использования в математике;

", если x имеет свойство A, тогда y еще z" (If-Else)

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

Ответ 9

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

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