假如我們要一個一個計算 1 到指定數字的加總
例如 1 到 3 為 1 + 2 + 3 = 6
(為了示範尾遞迴,先別用梯形公式)
def sum(0), do: 0
def sum(n) do
n + sum(n - 1)
end
這樣可以得到結果,但是這個作法沒有尾遞迴
這個執行的結果為
5 + sum(5 - 1)
5 + 4 + sum(4 - 1)
5 + 4 + 3 + sum(3 - 1)
5 + 4 + 3 + 2 + sum(2 -1)
5 + 4 + 3 + 2 + 1
15
這種寫法如果要計算的量非常大的話,會佔非常多的記憶體空間 (stack)
通常可以透過把 accumulator 加入參數內一起傳送來反過來
def sum(n), do: sum(n, 0)
def sum(0, acc), do: acc
def sum(n, acc) do
sum(n - 1, acc + n) # 最後呼叫的是自己
end
執行的結果就變成
sum(5)
sum(5, 0)
sum(4, 5)
sum(3, 9)
sum(2, 12)
sum(1, 14)
sum(0, 15)
15
可以使用同一個 stack
Enum.map
, Enum.reduce
等內建的函式,就一定會是尾遞迴優化