递归和尾调用优化示例

ada*_*ott 2 functional-programming elixir

我正在尝试学习 Elixir 和函数编程,但在理解 Elixir in Action 一书中的这个例子时遇到了困难。

defmodule ListHelper do
  def sum([]), do: 0
  def sum([head | tail]) do
    head + sum(tail)
  end
end

ListHelper.sum([12,3,4])
Run Code Online (Sandbox Code Playgroud)

这个的返回值是 19,但我不明白的是这些值是如何累积的。

我认为 head 正在不断更新,然后当模式匹配到[]然后累积的 head 将被添加到0并且该函数将退出,但是在使用它之后我现在认为这不是正在发生的事情。有人可以为这个例子中发生的事情提供另一种解释吗?如果我需要解释更多,我可以尝试重新审视这个。

sep*_*p2k 6

sum([head | tail])head + sum(tail)sum([12,3,4])12 + sum([3,4])sum([3,4])3 + sum([4])sum([4])4 + sum([])sum([])0,所以我们总共得到:

sum([12,3,4]) = 12 + sum([3,4])
              = 12 + 3 + sum([4])
              = 12 + 3 + 4 + sum([])
              = 12 + 3 + 4 + 0
              = 19
Run Code Online (Sandbox Code Playgroud)

递归调用sum不是尾调用,所以这里不会发生尾调用优化。为了实现 TCO,需要递归调用sum成为最后一个。

defmodule ListHelper do
  def sum([], acc), do: acc
  def sum([head | tail], acc),
    do: sum(tail, acc + head)
end

ListHelper.sum([12,3,4], 0)
#? 19
Run Code Online (Sandbox Code Playgroud)