2

MSDNのドキュメントによると、再帰関数を記述しているときに、accumulator 引数を使用すると、関数の末尾が再帰的になり、スタック スペースが節約されます。リスト内のすべての数値の合計を計算するために、MSDN サイトで与えられた 2 つの例を使用しています。

最初に末尾再帰なし-

let rec Sum myList =
    match myList with
    | [] -> 0
    | h::t -> h + Sum t

そして今、テール再帰を使って-

let Sumtail list =
    let rec loop list acc =
        match list with
        | h::t -> loop t acc + h
        | [] -> acc
    loop list 0

両方の関数を input で実行します[1..100000]。関数Sumはこのリストの合計を正常に計算しますが、パスするとスタックオーバーフロー例外が発生します[1..1000000] が、2 番目の関数は末尾再帰を使用するため、最初の関数よりもパフォーマンスが向上するはずですが、Sumtail 失敗します。[1..100000]再帰関数に影響を与える他の要因はありますか?

4

1 に答える 1

10

2番目の関数は、 の最後の操作になるように解析loop t acc + hされるため、末尾再帰ではありません。(loop t acc) + h+loop

関数が末尾再帰になるように変更loop t acc + hします。loop t (acc + h)

于 2012-04-11T12:26:03.567 に答える