私は再帰関数fact
を持っています。この関数は、その内部の式かそれ以外の式から呼び出すことができます。OCamlで再帰関数の静的変数を定義する
Iは、可変v
でfact
を関連付けたいたびfact
がv
が初期化され、外部(別の関数)から呼び出され、その値はfact
内で変更することができるが、ときに初期化することができない決してようfact
はの中から呼び出されます。
次のコードは、私のニーズに合った、が、1つの問題は、v
は、グローバル変数として定義されていることである、と私は美しい見つからない外部からfact
を呼び出す前にv := init
を行う必要があります。
let init = 100
let v = ref init
let rec fact (n: int) : int =
v := !v + 1;
if n <= 0 then 1 else n * fact (n - 1)
let rec fib (n: int) : int =
if n <= 0 then 0
else if n = 1 then (v := !v + 50; 1)
else fib (n-1) + fib (n-2)
let main =
v := init;
print_int (fact 3);
print_int !v; (* 104 is expected *)
v := init;
print_int (fib 3);
print_int !v;; (* 200 is expected *)
もっと良い実装をお考えですか?
変数 'v'は' fact'関数よりも*スコープ*が大きいものの、* static *とは言いません。 – huitseeker
@huitseeker:C言語の用語は、静的な*としてローカル関数の変数を定義すると、最初の呼び出しでのみ初期化され、後の呼び出しで同じ値が再利用されます。これは、関数呼び出し間で内部情報を伝播するために使用されることがよくあります。(初期のFortransのように、すべての関数変数が静的であるような言語もあります。つまり、コンパイラーはスタック上に動的なフレーム割り振りの概念を持たず、コンパイル時にすべてが割り当てられました。同じ関数が同時に生きています;再帰はありません) – gasche