exn型,exception宣言

Not_found とか Division_by_zero とかいう例外は,じつは exn型のコンストラクタ。例外コンストラクタと呼ぶ。

コンストラクタの型を見ると

# Division_by_zero;;
- : exn = Division_by_zero

exn型であることがわかる。同様に raise の型も。

# raise;;
- : exn -> 'a = <fun>

exn型には後からコンストラクタを追加することができる。これが新しい例外を宣言することに相当し,exception宣言を使う。

# exception Other_exception;;
exception Other_exception
# Other_exception;;
- : exn = Other_exception

引数をとる例外の場合は of に続けて引数の型をかけばいい。

# exception Another_exception of string;;
exception Another_exception of string
# Another_exception "some error";;
- : exn = Another_exception "some error"

練習問題 7.2

整数リストの要素すべての積を返す関数 prod_list を定義しなさい。リスト要素の一つでも 0 が含まれている場合には,prod_list の適用結果は常に 0 になるので,例外処理を使用 して,0 を発見したら残りの計算を行わずに中断して 0 を返すように定義しなさい。

まずは 0 をかけるという例外を宣言しよう。

# exception Multiple_zero;;
exception Multiple_zero

でもって prod_list の定義。

# let prod_list lis =
let prod' x y = if y = 0 then raise Multiple_zero else x * y in
try List.fold_left prod' 1 lis with
Multiple_zero -> 0
;;
val prod_list : int list -> int = <fun>

これでいいはず。

# prod_list [1; 3; 7; 2; 9];;
- : int = 378
# prod_list [5; 2; 0; 8; 4];;
- : int = 0