2012-01-16 62 views
3

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

まず、カウンターで何をしようとしているのかちょっと混乱していますが、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 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 
しようとしているものである

let someFunction n = 
    let rec aux count = 
     if count >= n then count 
     else aux (count+1) in 
    aux 0 ;; 

:良いアイデアは)あなたは参照せずにこれを行うことができます

一方で、あなたはsomeFunctionが呼び出された後、あなたはsomeFunction定義と同じスコープレベルでその参照カウンタが必要になりますどのように多くの時間を追跡したい、場合は、のようなもの:

あり
let count = ref 0 ;; 
let rec someFunction n f = 
    if !count >= 123 then count 
    else (
    incr count; 
    f n; 
    someFunction n f 
) ;; 
+0

編集:申し訳ありませんが、ページを更新していません、あなたが今書き込んだものを読んでいます – Kevin

+0

おそらく私の元のコードスニペットは明確ではありませんでした。 someFunctionが再帰的に何回呼び出されたかを追跡したいだけでした。これはまだ私にとって非常に混乱しています、そして、私はあなたが今書き込んだことを理解しようとしています。 – Kevin

+0

@ user1151063:もう一度やり直して最後のコードスニペットを見てみましょう。私が知る限り、あなたの質問のコードで達成しようとしているものです。 – aneccodeal

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を、それまでに何度も呼び出された回数を示す追加の引数を取る代わりのバージョンに置き換えるだけです。最初に関数の最後の行と呼ぶとき、ゼロで開始し、その後は毎回得られる値より1つ上の値を渡します。

+0

ご協力ありがとうございます! – Kevin