small medium large xlarge

• Write a function `mapsum` that takes a list and a function. It applies the function to each element of the list, and then sums the result, so

``````iex> MyList.mapsum [1, 2, 3], &1 * &1
14
``````

A Possible Solution</summary>

```defmodule MyList do

def mapsum([], _fun),            do: 0
def mapsum([ head | tail ], fun), do: fun.(head) + mapsum(tail, fun)

end

IO.puts MyList.mapsum([1, 2, 3], &1 * &1)  #=> 14
```

</details>

```defmodule MyList do
def mapsum([], _), do: 0
def mapsum([head | tail], fun) do
end
defp mapsum([head | tail], value, fun) do
end
defp mapsum([], value, _), do: value
end
```
```defmodule MyList do
def map([], _func), do: []
def map([ head | tail ], func), do: [ func.(head) | map(tail, func) ]

def reduce([], value, _) do
value
end

def reduce([head | tail], value, fun) do
end

def mapsum(list, fun) do
map(list, fun) |> reduce(0, &(&1 + & 2))
end
end
```
``````
defmodule Mylist do
end

def mapsum([head | []], _func) do
end
end

``````
``````defmodule MyList do
def map([], _func), do: []

def sums([]), do: 0

def mapsum(list, func), do: map(list, func) |> sums
end
``````

Using an accumulator:

``````defmodule MyList do
def mapsum(list, func), do: _mapsum(list, func, 0)
defp _mapsum([], _func, accum), do: accum
defp _mapsum([ head | tail ], func, accum) do
end
end
``````

Or to reuse existing MyList code:

``````def mapsum(list, func) do
list |> map(func) |> sum
end
``````

Hi Dave, even though the mapsum call is perfect in the book, the call above the possible solution on top of this page no longer works:

``````iex> MyList.mapsum [1, 2, 3], &1 * &1
** (CompileError) iex:1: unhandled &1 outside of a capture
``````

The call is wrong, should be: MyList.mapsum [1,2,3], &(&1*&1)

```defmodule MyList do
def mapsum([], func), do: 0
end
```
``````
def mapsum([]), do: []
def mapsum(list, func), do: _mapsum(list, func, 0)
defp _mapsum([], _func, total), do: total
defp _mapsum([ head | tail ], func, total), do: _mapsum(tail, func, total + func.(head))
``````

I leveraged the existing map and reduce functions:

``````  def mapsum(list, func) do
list
|> map(func)
|> reduce(0, fn a, b -> a + b end)
end
``````
``````defmodule MyList do
def mapsum(list, func) do
_mapsum(list, func, 0)
end

#Private functions
defp _mapsum([], _, total) do
total
end

defp _mapsum([head | tail], func, total) do
end
end

#Calling the functions...
IO.puts MyList.mapsum [], &(&1 * &1)          #=> 0
IO.puts MyList.mapsum [1, 2, 3], &(&1 * &1)   #=> 14
``````

Is it cheating to use the built-in map and reduce functions?

``````defmodule MyList do
def mapsum(a, f) do
Enum.reduce( (Enum.map a, f), 0, &(&1 + &2) )
end
end
``````
``````MyList.mapsum [1, 2, 3], &(&1 * &1)
=> 14
``````
```defmodule MyList do
def mapsum([], _func), do: 0

end

```

I reused the reduce function:

``````def mapsum(list, func) do
reduce(list, 0, &(func.(&1) + &2))
end
``````

This is my solution:

``````def mapsum(list, fun), do: reduce(list, 0, &(&1 + fun.(&2)))
``````

Where reduce is the function defined previously in the same module.

I choosed

``````fn acc, elem -> ...
``````

for my update function in reduce.

``````def mapsum([], _), do: 0
``````
``````def mapsum(lista, fun), do: _mapsum(lista, 0, fun)
defp _mapsum([], v_inicial, _), do: v_inicial
defp _mapsum([h|t], v_inicial, fun), do: _mapsum(t, v_inicial+fun.(h), fun)
``````
``````
def mapsum([], _, value), do: value
def mapsum([head | tail], func, total \\ 0) do
end

``````
`````` def mapsum(list, func), do: _mapsum(list, func, 0)

defp _mapsum([], _func, acc), do: acc

defp _mapsum([head | tail], func, acc) do
end
``````
``````
defmodule MyList do

# Principal function

def mapsum(a, start \\ 0 )
def mapsum([], start), do: start

def mapsum([head | tail], start) do
end

# private function

defp func1(x, y) do
(x*x) + y
end

end

``````

This worked for me!

``````defmodule MyList do

def mapsum(list, func), do: _mapsum(list, 0, func)

# private functions that actually do the work
defp _mapsum([], total, _func)  do
total
end

defp _mapsum([head | tail], total, func) do
end

end
``````
``````defmodule MyList do
def mapsum(list, func) when is_list(list) do
list
|> map(func)
|> reduce(&(&1 + &2))
end

def reduce(list, value \\ 0, func)
def reduce([], value, _), do: value
def reduce([head | tail], value, func) do