OCaml: сопоставление с образцом против операторов If / else - PullRequest
15 голосов
/ 24 сентября 2011

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

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

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

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

Когда мне следует использовать каждую из них?

Ответы [ 4 ]

18 голосов
/ 24 сентября 2011

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

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 голосов
/ 24 сентября 2011

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

  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 в операторе match не ссылается на x в операторе let над ним, а является именем шаблона.В таких случаях вам нужно использовать if операторов.

0 голосов
/ 01 февраля 2019

Для меня if..then..else эквивалентно совпадению .. с |правда -> .. |false -> .., но есть синтаксический сахар, если вы сталкиваетесь с случаями с сопоставлением вложенных шаблонов, использование if..else в чересстрочном порядке может помочь вам избежать использования begin ... end для разделения другого уровня шаблонов

match .. with
| true -> 
    if .. then 
      match .. with
      | true -> ..
      | false -> ..
    else
      ...
| false -> ...

более компактен, чем

match .. with
| true ->
   begin 
    match .. with
    | true -> 
       begin
         match .. with
         | true -> ..
         | false -> ..
       end
    | false -> 
      ...
   end
| false -> ...
0 голосов
/ 17 марта 2016

Сопоставление с образцом допускает деконструкцию составных типов данных и, в целом, возможность сопоставления с образцом в рамках данной структуры данных, а не использование условий, таких как структура if .. then. Сопоставление с образцом может также использоваться для случаев логического равенства с использованием конструкции типа | x when (r == n). Я также должен добавить, что сопоставление с образцом намного эффективнее, чем конструкции if ... then .., так что используйте это свободно!

...