我有一个递归函数fact
,它可以从它内部的表达式或其外部的表达式中调用。在OCaml中为递归函数定义一个静态变量
我想fact
具有可变v
相关联,使得每次fact
从外(另一功能)调用,v
被初始化,并且其值可以内部fact
被改变,但绝不可时被初始化fact
从内部调用。
下面的代码适合我的需要,但一个问题是,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'函数更大的* scope *,我不会将其称为* static *。 – huitseeker 2011-12-28 20:24:04
@huitseeker:我想这个术语来自C语言,如果你将一个局部函数变量定义为* static *,它只会在第一次调用时被初始化,并且在以后的调用中会重复使用相同的值。这通常用于跨函数调用传播内部信息。(甚至有早期的Fortrans等语言,其中所有的函数变量都是静态的,也就是说编译器没有在栈上动态分配帧的概念,所有的东西都是在编译时分配的,特别是你不能有两次调用相同的函数同时存在;没有递归) – gasche 2011-12-28 23:26:19