OCaml: соответствие шаблонов vs операторам If/else
Итак, я совершенно не знаком с OCaml и довольно медленно перемещаюсь, выполняя свои первые функции. Одна вещь, с которой мне трудно понять, - это когда использовать возможности сопоставления с образцами, например
let foo =
[] -> true
| _ -> false;;
vs с использованием структуры if else, такой как
let foo a =
if a = [] then true else false;;
Когда я должен использовать каждый?
Ответы
Ответ 1
Я не думаю, что есть четкий ответ на этот вопрос. Во-первых, очевидный случай сопоставления с образцом - это когда вам нужно уничтожить, например:
let rec sum = function
| [] -> 0
| head :: tail -> head + sum tail;;
Другим очевидным случаем является то, что вы определяете рекурсивную функцию, сопоставление шаблонов делает условие края более четким, например:
let rec factorial = function
| 0 -> 1
| n -> n * factorial(n - 1);;
вместо:
let rec factorial = function n ->
if n = 0 then
1
else
n * factorial(n-1);;
Это не может быть отличным примером, просто используйте свое воображение, чтобы понять более сложные краевые условия!; -)
В терминах регулярных (скажем, C-подобных) языков, я мог бы сказать, что вместо тройного оператора вы должны использовать сопоставление шаблонов вместо switch
/case
и if
. Для всего остального это своего рода серая зона, но сопоставление с образцами обычно предпочтительнее в семействе языков ML.
Ответ 2
Насколько я знаю, существенная разница заключается в том, что выражение в стражах в выражении соответствия - это pattern, что означает, что вы можете делать что-то которые позволяют разбить форму (уничтожить) согласованное выражение, как показал Николя в своем ответе. Другим следствием этого является такой код:
let s = 1 in
let x = 2 in
match s with
x -> Printf.printf "x does not equal s!!\n" x
| _ -> Printf.printf "x = %d\n" x;
не будет делать то, что вы ожидаете. Это связано с тем, что x
в инструкции соответствия не ссылается на x
в выражении let выше, но это имя шаблона. В таких случаях вам нужно использовать операторы if
.
Ответ 3
Согласование шаблонов позволяет разложить составные типы данных и, в целом, способность сопоставлять шаблон внутри данной структуры данных, а не использовать условные обозначения, такие как структура if.. then. Соответствие шаблону также можно использовать для логических случаев равенства, используя конструкцию типа \x when (r == n). Я также должен добавить совпадение шаблонов намного эффективнее, чем если бы... тогда... конструирует, поэтому используйте его либерально!
Ответ 4
Для меня if..then..else эквивалентно совпадению.. с | правда ->.. | false ->.., но есть синтаксический сахар, если вы сталкиваетесь с случаями с сопоставлением вложенных шаблонов, использование if..else может помочь вам избежать использования begin... end для разделения различных уровней шаблонов