我在算法書中讀到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#代碼)。
我的問題是,我不確定這實際上是尾遞歸。你能確認它是什麼嗎?如果不是,爲什麼?最終,當人們說阿克曼函數不是原始遞歸時,這意味着什麼?
謝謝!
當您傳遞該lambda表達式時,您仍然在構建函數調用的「堆棧」。 – 2010-12-12 22:47:22
是的,它是尾遞歸的。你可以用'-dlinear'選項用ocamlopt編譯文件。這應該可以幫助您確定您的功能是否使用尾部呼叫。 – nlucaroni 2010-12-13 16:36:11