5

Just trying to do simple sum of list values.

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]) 

But I get this error:

**(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**
legoscia
  • 39,593
  • 22
  • 116
  • 167
Krab
  • 6,526
  • 6
  • 41
  • 78

5 Answers5

17

You need to use lowercase letters for variable and functions names. Identifiers starting with uppercase are reserved for modules:

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
Chris McCord
  • 8,020
  • 1
  • 37
  • 26
  • 2
    It would be unwise to implement a sum_list function this way because you would not benefit from Elixir's tail call optimisation. `h + sum_list(t)` would be executed as follows 1. `sum_list(t)` 2. `h +` So the last function call here would be the `+`. This would mean that if you had a very long list you could get a stack overflow error. Somewhat ironic, I know. – James Stonehill Apr 15 '18 at 15:37
8

To improve upon Chris's solution, if you want your sum function to be tail recursive, you'd need to modify it a bit to be:

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
bitwalker
  • 9,061
  • 1
  • 35
  • 27
4

If you are going to use Enum.reduce you can go simpler:

defmodule Mth do
  def sum_list(list), do: Enum.reduce(list, 0, &(&1 + &2))
end
emancu
  • 145
  • 1
  • 9
1

Just for sake of completeness this would also work:

defmodule Mth do

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

  defp do_sum_list(l,i_acc), do: Enum.reduce(l, i_acc, fn(x, accum) -> x + accum end)

end

I post this solely for reference for others who may find this question and it's answers.

Onorio Catenacci
  • 14,928
  • 14
  • 81
  • 132
0

Try this:

sum_list=[1,2,300]     
Enum.sum sum_list     
303
Florian
  • 2,796
  • 1
  • 15
  • 25