在 OCaml 雖然有提供 for 和 while 語法,但其實這兩個語法缺乏了 continue 和 break 的功能,某種程度上在鼓勵你寫遞迴,當然你遞迴寫的嚇嚇叫,隨手一揮就能輕鬆寫出需要的遞迴結構,你可能完全不需要這個功能。
不過在某些狀況下,for, while 寫出來的程式易讀性可能較好,這時就不得不思考能不能對這兩個功能作抽象並補足缺乏的功能。
exception Continue
exception Break
let continue () = raise Continue
let break () = raise Break
let for_loop s e step ~f =
let rec aux c =
if not (c >= s && c < e) then
()
else (
try
f c;
aux (c + step)
with
| Continue -> aux (c + step)
| Break -> ()
| e -> raise e
)
in
aux s
;;
let rec while_loop ~cond ~f =
if cond () then (
try
f ();
while_loop ~cond ~f
with
| Continue -> while_loop ~cond ~f
| Break -> ()
| e -> raise e
)
;;透過拋出例外的方式來模擬 continue 和 break 的功能,這樣就可以在 for_loop 和 while_loop 內中斷或繼續。
(* while loop *)
let () =
let sum = ref 0 in
let cond () = !sum < 100 in
while_loop ~cond ~f:(fun _ ->
let s = !sum in
if s > 50 then
break ()
else if s = 25 then (
sum := s + 26;
continue ()
) else
sum := s + 1);
print_int !sum (* 51 *)
;;
(* for loop *)
let () =
let sum = ref 0 in
for_loop 0 10 1 ~f:(fun i ->
let s = !sum in
if i mod 2 = 1 then
continue ()
else if s > 10 then
break ()
else
sum := s + i);
print_int !sum (* 12 *)
;;