The problem

- Given a list of numbers, use recursion to find (1) the size of the list, (2) the maximum value, and (3) the minimum value.

The solution

- Let's go ahead and leverage
**recursion**in conjunction with**pattern matching**to find the size of the list.

```
defmodule MyEnum do
def size([h|t]), do: + size(t)
def size([]), do: 0
end
```

- Now it's time to find minimum/maximum

```
defmodule MyEnum do
def maximum([h|t]), do: maximum(t,h)
def maximum([]), do: nil
defp maximum([h|t],m), do: maximum(t,Kernel.max(m,h))
defp maximum([],m), do: m
def minimum([h|t]), do: minimum(t,h)
def minimum([]), do: nil
defp minimum([h|t],m), do: minimum(t,Kernel.min(m,h))
defp minimum([],m), do: m
end
```

- It looks to me that in general minimum/maximum functions have very similar algorithm. Both of them accumulate some value. The only part that differs here is calculation. Let's leverage
**higher-order**function by introducing**reduce**function.

```
defmodule MyEnum do
def maximum(list), do: reduce(list,&max(&1,&2))
def minimum(list), do: reduce(list,&min(&1,&2))
def reduce([h|t],acc, fun), do: reduce(t,fun.(h,acc),fun)
def reduce([],acc, fun), do: acc
def reduce([h|t],fun), do: reduce(t,h,fun)
def reduce([],fun), do: nil
end
```