-2

I'm trying to make a function that finds the local Maximum number in a list.

localMaxima :: [Integer] -> [Integer]
localMaxima [] = []
localMaxima [x] = []
localMaxima (e1:e2:e3:xs)
    |    (e2 > e3) && (e2 > e1) = e2 : (localMaxima (e2:(e3:xs)))
    |    otherwise = (localMaxima (e2:(e3:xs)))

After inputting a list of [2,3,4,1,5], the console outputs:

Non-exhaustive patterns in function localMaxima

Unshure
  • 3
  • 1

1 Answers1

0

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 _ = []
Community
  • 1
  • 1
Lorenzo
  • 2,160
  • 12
  • 29