例外を発生させる raise

OCaml には例外処理の仕組みがある。例外を発生させるには raise を使う。raise は例外の名前を引数にとる。

fact関数の引数が負の時に例外を発生する例:

# let rec fact n =
if n < 0 then raise (Invalid_argument "fact: negative argument")
else if n = 0 then 1
else n * fact (n - 1)
;;
val fact : int -> int = <fun>

例外は関数の型とは関係がないので,気にせずに使える。

# fact (-2);;
Exception: Invalid_argument "fact: negative argument".

例外を処理する try

発生した例外を捕捉して処理するのが try。

# try fact (-2) with Invalid_argument _ -> 0;;
- : int = 0
# try fact 3 with Invalid_argument _ -> 0;;
- : int = 6

match によるパターンマッチングに似ている。まず try と with に囲まれた部分を評価し,例外が発生したら with 以降の部分で例外名でパターンマッチして処理する。上の1番目の場合には例外が発生しているので値が0,2番目の場合には発生していないので値はそのまま6になっている。

Invalid_argument の後の _ は Invalid_argument の引数を示している。ここでは使わないのでワイルドカードにしているけど,きちんと書く場合には発生する例外と同じでないといけないらしい。

# try fact (-2) with Invalid_argumetn "fact: invalid argument" -> 0;;
Characters 19-60:
try fact (-2) with Invalid_argumetn "fact: invalid argument" -> 0;;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Unbound constructor Invalid_argumetn

ということは,同じ名前の例外でも引数の違いによって処理を分けることができるのかな。