## 11 ways to write your last Haskell program

Published 2014-10-02 in sections English, Haskell.

At my university, we recently held an exam that covered a bit of Haskell, and a simple warm-up question at the beginning asked the students to implement `last :: [a] -> a`. We did not demand a specific behaviour for `last []`.

This is a survey of various solutions, only covering those that are actually correct. I elided some variation in syntax (e.g. guards vs. `if`-`then`-`else`).

Most wrote the naive and straightforward code:

``````last [x] = x
last (x:xs) = last xs``````

Then quite a few seemed to be uncomfortable with pattern-matching and used conditional expressions. There was some variety in finding out whether a list is empty:

``````last (x:xs)
| null xs == True = x
| otherwise       = last xs

last (x:xs)
| length (x:xs) == 1 = x
| otherwise          = last xs

last (x:xs)
| length xs == 0 = x
| otherwise      = last xs

last xs
| lenght xs > 1 = last (tail xs)
| otherwise     = head xs

last xs
| lenght xs == 1 = head xs
| otherwise      = last (tail xs)

last (x:xs)
| xs == []  = x
| otherwise = last xs``````

The last one is not really correct, as it has the stricter type `Eq a => [a] -> a`. Also we did not expect our students to avoid the quadratic runtime caused by using `length` in every step.

The next class of answers used `length` to pick out the right elemet, either using `(!!)` directly, or simulating it with `head` and `drop`:

``````last xs = xs !! (length xs - 1)

last xs = head (drop (length xs - 1) xs)``````

There were two submissions that spelled out an explicit left folding recursion:

``````last (x:xs) = lastHelper x xs
where
lastHelper z [] = z
lastHelper z (y:ys) = lastHelper y ys``````

And finally there are a few code-golfers that just plugged together some other functions:

``last x = head (reverse x)``

Quite a lot of ways to write `last`!