我是Ocaml的新手。我遇到的问题是跟踪函数中递归调用的数量。
例如,我写了一个以下函数:
let rec someFunction n =
let digi = someOtherFunction n in
match digi with
| x when x > 123 -> someFunction digi
| x -> [want to output # of recursive calls] ;;
我该怎么做呢?我尝试创建一个变量,但是如果我在someFunction中有它,它就会一直重置为初始值。我基本上想要做的是这样的事情:
while ( x > 123) {
count++;
someFunction(x);
}
return count;
请原谅我,如果这是非常微不足道的话。
答案 0 :(得分:2)
首先,我对你试图用柜台做什么感到有点困惑,难道你不想让它数到123吗?这不意味着你需要:
while (count < 123) { count++; someFunction(count); }
...意味着你计算它被调用的次数,直到它达到123然后退出。
如果你想要计算函数调用到一定限制的次数,那么你可以使用这样的ref:
let someFunction n =
let count = ref 0 in
let rec aux () =
if !count >= n then count
else (
incr count;
(* do the stuff you wanted to do in someFunction here *)
aux () ) in
aux () ;;
如果你想避免可变状态(通常是一个好主意)那么你可以在没有参考的情况下做到这一点:
let someFunction n =
let rec aux count =
if count >= n then count
else aux (count+1) in
aux 0 ;;
也许这就是你要做的事情?:
let someOtherFunction n =
Printf.printf "n is: %d\n" n;;
let someFunction n f =
let rec aux count =
if count >= n then count
else (
f count;
aux (count+1)
) in
aux 0 ;;
# someFunction 10 someOtherFunction ;;
n is: 0
n is: 1
n is: 2
n is: 3
n is: 4
n is: 5
n is: 6
n is: 7
n is: 8
n is: 9
- : int = 10
另一方面,如果你想跟踪someFunction被调用的次数,那么你将需要与someFunction定义相同的范围级别的ref计数器,如:
let count = ref 0 ;;
let rec someFunction n f =
if !count >= 123 then count
else (
incr count;
f n;
someFunction n f
) ;;
答案 1 :(得分:1)
有几种方法可以做到这一点。一种方法是使用像你编写的while循环来做,但引用允许变量能够改变值。
let x := starting_value;
let count := 0;
while ( !x > 123) do (
count := count + 1;
x := someFunction(x)
) done;
!count
或者,如果您想编写纯函数代码,可以添加一个辅助函数,如下所示:
let someFunction n =
let rec someFunctionHelper n count =
let digi = someOtherFunction n in
match digi with
| x when x > 123 -> someFunctionHelper digi (count + 1)
| x -> count
in
someFunctionHelper n 0
第二种方式是我如何写它。从本质上讲,我们只是用一个替代版本替换原始代码中的someFunction,这个版本需要一个额外的参数来指示到目前为止已经调用了多少次。当我们第一次(函数的最后一行)调用它时,我们从零开始,然后在那之后,我们传递的值比我们每次得到的值高一号。