small medium large xlarge

This is a problem set in the elixir Book to find out the maximum value in a list.

``````defmodule Maximum do
def greater(a,b) when a > b , do: a
def greater(a,b) when a < b , do: b

def max([]), do: IO.puts "What The hell? How am i supposed to do that ?"
def max([head | tail] ) do
end
end

Maximum.max [2,3,4,5,9,1]
``````

Is there a better and more elegant way of doing this ?

Your `greater/2` exists as `Kernel.max/2`, so you can rewrite your code as:

``````defmodule Maximum do
# Renamed to max1 to make distinct from Kernel.max/2
def max1([]), do: raise "Error: Empty list"
end
``````

Note that your version won’t work with duplicates in the list (you need a `<=` case in your `greater/2`).

Another approach is to use `List.foldr/3` or `Enum.reduce/2`. You don’t need an accumulator, so the latter is probably best:

``````# Empty list handling propagates from Enum.reduce/2
def max2(list), do: Enum.reduce(list, &Kernel.max(&1, &2))
``````

This is arguably a more functional way to do it. As Dave writes in the book: Recursion is nice, but very very often you will (or should) end up using map/filter/fold or other higher-order functions instead.

There are probably a lot of other interesting ways to do it. Some functional programming humor about the possibilities: The Evolution of a Haskell Programmer