OCaml:模式匹配与If / else语句

时间:2011-09-24 02:37:39

标签: functional-programming if-statement pattern-matching ocaml

所以,我对OCaml完全不熟悉,并且在实现我的第一个功能方面进展缓慢。我无法理解的一件事是何时使用模式匹配能力,如

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

使用if else结构,如

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

我什么时候应该使用它们?

4 个答案:

答案 0 :(得分:17)

我认为这个问题没有明确的答案。首先,模式匹配的明显例子是你需要破坏时,例如:

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 / caseif来代替三元运算符。对于其他一切,它是一种灰色区域,但在ML系列语言中通常首选模式匹配。

答案 1 :(得分: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;

不会做你期望的。这是因为match语句中的x没有引用它上面的let语句中的x,但它是模式的名称。在这种情况下,您需要使用if语句。

答案 2 :(得分:0)

模式匹配允许解构复合数据类型,并且通常能够匹配给定数据结构中的模式,而不是使用if ... then结构之类的条件。模式匹配也可以用于使用| x when(r == n)类型构造的布尔相等情况。我还应该添加模式匹配比if ... then ..结构更高效,所以请大量使用它!

答案 3 :(得分:0)

对我来说,.. then..else等效于将..与|匹配。 true-> .. |假 - > ..,但有,如果你正面临着嵌套模式匹配的情况下语法糖,使用的if..else在隔行扫描方式可以帮助您避免使用开始...结束区分不同层次的模式

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 -> ...