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