アルゴリズムの本では、Ackermann関数をテール再帰的に行うことはできません(「反復に変換できません」ということです)。私はこれについてかなり混乱しているので、試してみました:この実装はテール再帰的ですか
let Ackb m n =
let rec rAck cont m n =
match (m, n) with
| 0, n -> cont (n+1)
| m, 0 -> rAck cont (m-1) 1
| m, n -> rAck (fun x -> rAck cont (m-1) x) m (n-1)
in rAck (fun x -> x) m n
;;
(それはOCaml/F#コードです)。
私の問題は、実際にはこれが末尾再帰であるかどうかはわかりません。それが確認できますか?そうでない場合、なぜですか?そして、最終的に、Ackermann関数が原始的な再帰的関数ではないと人々が言うとき、それはどういう意味ですか?
ありがとうございます!
ラムダを渡しているときでも、関数呼び出しのスタックを構築しています。 –
はい、テール再帰的です。ファイルを '-dlinear'オプションでocamloptでコンパイルすることができます。これは、関数がテールコールを使用しているかどうかを判断するのに役立ちます。 – nlucaroni