プログラミング in OCaml メモ

命令的な階乗関数の定義

8.3 制御構造 — 8.3.3 繰り返し

ここでは、手続き型言語(命令形言語)での階乗関数の定義を
OCamlを使って記述するとどうなるかが紹介されている。

命令的な階乗関数の定義

let fact n =
    let i = ref 1         (* 1が格納されるアドレスを i とする。初期値が 1 *)
    and res = ref 1 in    (* i と同じく、1が格納されるアドレス を res とする *)
    while (!i <= n) do    (* !1 は、アドレスに格納されている値 *)
        res := !res * !i; (* resに格納されている値と iに格納されている値を掛けて、res を書き換える *)
        i := !i + 1       (* !1 に 1 をたして、i を書き換える *)
    done;
    !res;;                (* resに格納された最終の値 *)

i と res には、ともに 1 が初期値としてセットされたが、
i と res は、参照先として同じ(アドレス)であるか?

let i = ref 1 and res = ref 1;;

!i = !res;;   (* true *) <-- 値は同じ 
!i == !res;;  (* true *) <-- == でも同じ
i = res;;     (* true *) <-- 構造的に同じ
i == res;;    (* false *) <-- 物理的に違う

結論として、i と res は、格納された値は同じでも、メモリ上のアドレスは違うということがわかる。

参考

階乗関数は、再帰を使うなら、以下のように定義できる。

let rec fact n =
    if n = 1 then 1
    else fact (n-1) * n;;