Elixir - 具有递归的列表值的总和

Kra*_*rab 5 erlang elixir

只是想尝试列出值的简单总和.

defmodule Mth do 

    def sum_list([]) do 
        0
    end

    def sum_list([H|T]) do
        H + sum_list(T)
    end

end

IO.puts Mth.sum_list([1, 2, 300]) 
Run Code Online (Sandbox Code Playgroud)

但我得到这个错误:

**(FunctionClauseError) no function clause matching in Mth.sum_list/1
    pokus.ex:3: Mth.sum_list([1, 2, 300])
    pokus.ex:14: (file)
    (elixir) src/elixir_lexical.erl:17: :elixir_lexical.run/2
    (elixir) lib/code.ex:316: Code.require_file/2**
Run Code Online (Sandbox Code Playgroud)

Chr*_*ord 13

您需要为变量和函数名称使用小写字母.以大写字母开头的标识符保留给模块:

defmodule Mth do 

  def sum_list([]) do 
    0
  end

  def sum_list([h|t]) do
    h + sum_list(t)
  end

end

iex> IO.puts Mth.sum_list([1, 2, 300])
303
:ok
Run Code Online (Sandbox Code Playgroud)

  • 以这种方式实现 sum_list 函数是不明智的,因为您不会从 Elixir 的尾调用优化中受益。`h + sum_list(t)` 将按如下方式执行 1. `sum_list(t)` 2. `h +` 所以这里的最后一个函数调用将是 `+`。这意味着如果您有一个很长的列表,您可能会收到堆栈溢出错误。有点讽刺,我知道。 (2认同)

bit*_*ker 7

为了改进Chris的解决方案,如果你希望你的sum函数是尾递归的,你需要稍微修改它:

defmodule Mth do 
  def sum_list(list), do: do_sum_list(list, 0)

  defp do_sum_list([], acc),    do: acc
  defp do_sum_list([h|t], acc), do: do_sum_list(t, acc + h)
end

iex> Mth.sum_list([1, 2, 300])
303
Run Code Online (Sandbox Code Playgroud)