Problem
As you can tell from the error, your pattern matching does not cover all the cases: what happens if you give it a list with 2 elements? e1:e2:[]
does not match any of your cases, resulting in a non-exhaustive patterns error.
Solution
The solution is fairly easy: add a base-case for a list with two elements only. Assuming a point on the boundary cannot be a local min/max, your function should look something like this.
localMaxima :: [Integer] -> [Integer]
localMaxima [] = []
localMaxima [x] = []
localMaxima [a,b] = []
localMaxima (e1:e2:e3:xs)
| (e2 > e3) && (e2 > e1) = e2 : (localMaxima (e2:(e3:xs)))
| otherwise = (localMaxima (e2:(e3:xs)))
Furthermore, you can simplify this even more by
- noting
:
is right-associative
- use pattern wildcard
_
- make your type signature more generic
You can now have
localMaxima :: Ord a => [a] -> [a]
localMaxima (e1:e2:e3:xs)
| (e2 > e3) && (e2 > e1) = e2 : localMaxima (e2:e3:xs)
| otherwise = localMaxima (e2:e3:xs)
localMaxima _ = []