OCaml:括在括号中的代码

时间:2012-09-19 16:35:11

标签: printing ocaml

我在 draw_string_in_box

中关注此Developing Applications with OCaml示例

给出的示例代码如下:

let draw_string_in_box pos str bcf col = 
 let (w, h) = Graphics.text_size str in
 let ty = bcf.y + (bcf.h-h)/2 in 
 ( match pos with 
       Center -> Graphics.moveto (bcf.x + (bcf.w-w)/2) ty 
     | Right  -> let tx = bcf.x + bcf.w - w - bcf.bw - 1 in 
                 Graphics.moveto tx ty 
     | Left   -> let tx = bcf.x + bcf.bw + 1 in Graphics.moveto tx ty  );
 Graphics.set_color col;
 Graphics.draw_string str;;

如果我删除“匹配”部分周围的括号,则代码将无效(无法打印任何内容)。知道为什么吗?

更一般地说,我应该何时将括号括在像这样的代码位?

感谢。

2 个答案:

答案 0 :(得分:5)

查看它的一种方法是在->语句的箭头match之后,您可以有一系列表达式(由;分隔)。如果没有括号,以下表达式看起来就像是match的最后一个案例的一部分。

;之后,您还可以拥有一系列表达式(由let分隔)。使用括号,以下表达式看起来像是let的一部分,这就是您想要的。

我个人避免使用;。这就是我如何处理这个问题!否则,您必须确定表达序列与采用序列的最内层构造一致。

答案 1 :(得分:3)

正如Jeffrey所解释的,如果删除括号,则Graphics.set_color col; Graphics.draw_string str语句被理解为| Left ->个案的一部分。

这个答案更多的是关于何时在这些代码摘录中使用括号。 在大多数情况下,模式匹配是函数的 last 表达式,例如:

let f x y =
  foo x;
  match y with
  | Bar -> Printf.printf "Found y=Bar!\n%!"; 42
  | Baz -> Printf.printf "Found y=Baz!\n%!"; 43

在这种情况下,您不需要括号。通常,它也是第一个,因此也是函数的唯一表达式:

let hd list = match list with
  | a :: _ -> a
  | [] -> invalid_arg "hd"

但是当你想在匹配后做事时,你需要告诉OCaml匹配结束的地方。这是您使用括号的地方:

let f x y =
  foo x;
  (match y with
  | Bar -> 42
  | Baz -> 43);
  (* do something, both when y is Bar and when it is Baz: *)
  qux x y;

同样适用于try ... with陈述:

let find_a_b a b list =
  (try print_int List.assoc a list
   with Not_found -> Printf.printf "Could not find a=%s.\n%!" a);
  (* Now do something whether or not we found a: *)
  (try print_int List.assoc b list
   with Not_found -> Printf.printf "Could not find b=%s.\n%!" b);

这里第一个括号是强制性的,秒是可选的,通常不写。