Ведение подсчета количества рекурсивных вызовов в Окамле - PullRequest
3 голосов
/ 16 января 2012

Я новичок в Окамле.У меня проблема с отслеживанием количества рекурсивных вызовов в функции.

Например, я написал следующую функцию:

    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;

Простите, если это что-то очень тривиальное.

Ответы [ 2 ]

2 голосов
/ 16 января 2012

Во-первых, я немного озадачен тем, что вы пытаетесь сделать со счетчиком, разве вы не хотите, чтобы он считал до 123? Не означает ли это, что вам нужно:

while (count < 123) { count++; someFunction(count); }

... означает, что вы подсчитываете, сколько раз он вызывается, пока не достигнет 123, а затем выйдет.

Если вы хотите сохранить количество обращений к функции до определенного предела, вы можете использовать следующую ссылку:

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, что-то вроде:

let count = ref 0 ;;
let rec someFunction n f = 
  if !count >= 123 then count
  else (
    incr count;
    f n;
    someFunction n f
  ) ;;
1 голос
/ 18 января 2012

Есть несколько способов сделать это.Один из них - сделать это с помощью цикла 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 из вашего исходного кода альтернативной версией, которая принимает дополнительный аргумент, который указывает, сколько раз он был вызван до сих пор.Когда мы вызываем его в первый раз (последняя строка функции), мы начинаем его с нуля, а затем после этого передаем число на единицу выше, чем то, что мы получали каждый раз.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...