Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Recursion 在Ocaml中记录递归调用的数量_Recursion_Ocaml - Fatal编程技术网

Recursion 在Ocaml中记录递归调用的数量

Recursion 在Ocaml中记录递归调用的数量,recursion,ocaml,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] ;; 我该怎么做呢?我尝试创建一

我是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] ;;
我该怎么做呢?我尝试创建一个变量,但如果我在某个函数中有它,它会一直重置为初始值。我基本上想做的是这样的:

     while ( x > 123) {
     count++;
     someFunction(x);
     }

     return count;
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 () ;;

如果这是非常琐碎的事情,请原谅我

首先,我有点搞不懂你想用计数器做什么,你不想让它数到123吗?这难道不意味着你需要:

while (count < 123) { count++; someFunction(count); }
如果希望避免可变状态(通常是个好主意),则可以在不使用ref的情况下执行此操作:

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
  ) ;;

有几种方法可以做到这一点。一种是像您编写的那样使用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

第二种方法是如何写。本质上,我们只是将原始代码中的某个函数替换为另一个版本,该版本使用一个额外的参数来指示到目前为止调用了多少次。当我们第一次调用它时(函数的最后一行),我们从零开始,然后,我们传递一个比每次都高的数字。

EDIT:抱歉,没有刷新页面,我正在阅读您现在编写的内容可能我的原始代码片段不清楚;我只是想记录某个函数被递归调用的次数。这仍然让我很困惑,我正在试图理解您现在写的内容。@user1151063:请再次尝试刷新,并查看最后一段代码片段-据我所知,这是您在问题代码中试图实现的。谢谢您的帮助。使用ref(reference?)是我要做的事情的必要条件吗?我还没有读过这方面的内容,因为我几天前才开始学习OCaml。@user1151063-这取决于你想做什么(我还不完全清楚)。如果您试图跟踪某个函数被调用的次数,那么是的,您似乎需要引入一些状态(ref就是这样做的,这是我在最后一个选项中显示的)。如果您只是尝试调用某个函数n次(正如while循环所建议的那样),那么我上面显示的倒数第二个选项在没有ref的情况下就可以完成。