保持Ocaml中递归调用次数的计数

时间:2012-01-16 01:24:27

标签: recursion ocaml

我是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;

请原谅我,如果这是非常微不足道的话。

2 个答案:

答案 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,这个版本需要一个额外的参数来指示到目前为止已经调用了多少次。当我们第一次(函数的最后一行)调用它时,我们从零开始,然后在那之后,我们传递的值比我们每次得到的值高一号。