Elixir basics · Lesson 14 (open contents)
Solve a list twice
Compare explicit recursion with `Enum.reduce/3`.
Run this first
Run it once, change one input, and compare the new result.
# Compare recursion with a library fold
defmodule Totals do
def sum([]), do: 0
def sum([head | tail]), do: head + sum(tail)
end
numbers = [1, 2, 3, 4]
{Totals.sum(numbers), Enum.reduce(numbers, 0, fn n, acc -> n + acc end)}- Both paths return 10, so the result is
{10, 10}.
Read from the first line down
- Read
sum([]): Stop at an empty list. - Read
sum([head | tail]): Handle one item and the remaining list. - Read
Enum.reduce/3: Fold values into one accumulator.
Symbols are not secret signs
sum([])Stop at an empty list.
sum([head | tail])Handle one item and the remaining list.
Enum.reduce/3Fold values into one accumulator.
Match each name to its meaning
base clause
A recursive function needs a clause that returns without calling itself.
recursive clause
The recursive clause handles one piece and calls itself with a smaller input.
fold
Enum.reduce/3 carries an accumulator through a collection.
Why these forms are useful
Run the example first. Predict one result, then change one input and run it again.
A recursive function needs a clause that returns without calling itself.
The recursive clause handles one piece and calls itself with a smaller input.
Close the answer and try
Multiply [2, 3, 4] with Enum.reduce/3.
Enum.reduce([2, 3, 4], ____, fn number, acc -> ____ end)Target result: Return 24.
Stuck? Read one hint
Start the accumulator at 1 and multiply it by each number.
After you run it, see one answer
Enum.reduce([2, 3, 4], 1, fn number, acc -> number * acc end)Think about it: What stops `Totals.sum/1`?
The sum([]) clause returns 0 without another call.
Remember these three lines
- 1
Every recursion needs a stopping clause.
- 2
Make recursive input smaller.
- 3
Prefer clear Enum functions for common collection work.