У меня есть рекурсивная функция fact
, которая может быть вызвана либо из выражения внутри него, либо из выражения вне его.Определить статическую переменную для рекурсивной функции в OCaml
Я хотел бы связать fact
с переменной v
, таким образом, что каждый раз, когда fact
вызывается из вне (другой функции), v
инициализируется, и его значение может быть изменено внутри fact
, но никогда не может быть инициализирована, когда fact
вызывается от внутри.
Следующий код подходит моя потребность, но одна проблема заключается в том, что v
определяется как глобальная переменная, и я должен сделать v := init
перед вызовом fact
из-за пределов, которые я не нахожу красивым.
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, где, если вы определяете локальную переменную функции как * static *, она инициализируется только при первом вызове, и одно и то же значение повторно используется при последующем вызове. Это довольно часто используется для распространения внутренней информации по вызовам функций.(Есть даже такие языки, как ранний Фортранс, где все переменные функции были статическими, то есть у компилятора не было понятия о распределении динамического кадра в стеке, все было выделено во время компиляции, и, в частности, у вас не могло быть двух вызовов одна и та же функция в режиме реального времени, без рекурсии.) – gasche