Подтвердить что ты не робот

OCaml: соответствие шаблонов vs операторам If/else

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

let foo = 
[] -> true
| _  -> false;;

vs с использованием структуры if else, такой как

let foo a = 
if a = [] then true else false;;

Когда я должен использовать каждый?

4b9b3361

Ответ 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 для разделения различных уровней шаблонов