recursion - Elixir 和默认参数中的尾递归调用

标签 recursion pattern-matching default tail-recursion elixir

我正在用 Elixir 写一个简单的例子,虽然它有效,但我并不真正理解如何。

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

当我调用 MyList.sum 时,我得到了预期的结果
sum([]) => 0
sum([1,2,3]) => 6

我无法在第二个总和中添加默认参数,因为编译器抛出错误
def sum/2 has default values and multiple clauses, use a separate clause for declaring defaults

所以我的问题是, sum([1,2,3]) 是如何工作的?它不符合任何定义。
函数仍然是尾递归的吗?

最佳答案

当您有一个带有可选参数的多子句时,您可以将默认值指定为无正文子句:

defmodule MyList do
  def sum(list, acc \\ 0) # sets up default arguments

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

关于你的例子,我只是猜测,但我认为你的代码相当于以下内容:
defmodule MyList do
  # implicitly generated due to default argument
  def sum(list), do: sum(list, 0)

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

这就是为什么sum([1,2,3])也有效。

编辑 :
该函数绝对是尾递归的。如果一个函数做的最后一件事是调用另一个函数(或它本身),那么它就是尾调用。所以在这种情况下,当我们调用 sum(tail, acc + head) ,首先计算参数,然后发生尾递归调用。

关于recursion - Elixir 和默认参数中的尾递归调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22164902/

相关文章:

java - 显示注册某个字符串的所有可能组合的递归方法

PHP 数组 - 如何将一维数组转换为嵌套的多维数组?

algorithm - 动态规划 : Do I have overlapping sub-problems?

.net - 将标识符模式与 `as` 模式相结合

css - 删除/完全重置 img 上的继承样式

python - 如何创建用于递归生成迭代函数的函数

java - 给定字符串中的混合重音字符和普通字符在搜索时在 Java 中不起作用

regex - 无法匹配正则表达式中的字符串文字

python - Python 中的 default() 方法

java - 未找到默认 Activity 启动 Activity 时出错