6

私は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

コンパイラがエラーをスローするため、2 番目の合計にデフォルト パラメータを追加できません

def sum/2 has default values and multiple clauses, use a separate clause for declaring defaults

私の質問は、なぜ sum([1,2,3]) が機能するのですか? どの定義とも一致しません。関数はまだ末尾再帰的ですか?

4

1 に答える 1

9

オプションの引数を持つ複数節がある場合、デフォルトを本文のない節として指定できます。

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)、最初に引数が計算され、次に末尾再帰呼び出しが発生します。

于 2014-03-04T08:16:42.317 に答える