Smite
Smite

Reputation: 59

How do I get rid of the non-exhaustive patterns error in Haskell?

I'm very new to Haskell so I'm afraid I haven't fully understood how it works yet. Following method is supposed to determine whether a matrix is an actual matrix or not.

isMatrix :: [[Int]] -> Bool
isMatrix [[x]] = True 
isMatrix [x] = True

So isMatrix [[1,2],[3,2]] is supposed to be true for example and [[1],[3,2]] is supposed to be false.

Now I'm receiving the error 'Non-exhaustive patterns in function isMatrix'. Am I lacking certain cases and if so, what should I do?

If someone could explain that to me, I'd be very grateful.

Thanks in advance!

Upvotes: 0

Views: 212

Answers (1)

chi
chi

Reputation: 116139

You can ask the compiler about the missing cases by turning on warnings with the -Wall flag. I strongly recommend to keep warnings always enabled. For your code the compiler reports:

example.hs:11:1: warning: [-Wincomplete-patterns]
    Pattern match(es) are non-exhaustive
    In an equation for `isMatrix':
        Patterns not matched:
            []
            ([]:_:_)
            ([_]:_:_)
            ((_:_:_):_:_)

These are the cases you are not handling:

  • [] the empty matrix, with no rows
  • []:_:_ a matrix with at least two rows, the first row being empty
  • [_]:_:_ a matrix with at least two rows, the first row having only one element
  • (_:_:_):_:_ a matrix with at least two rows, the first row having at least two cells

This is because [x] is a list of length one, in your case a matrix with only one row x. Further, [[x]] is a matrix with only one row having only one element x (by the way, don't use the same variable name for rows and cells, it's confusing). Many other cases are unspecified.

Note that your code is wrong even on the cases you handle: e.g., isMatrix [[1,2,3,4,5]] returns True since it has only one row, but that's not a matrix.

There are many ways to approach your problem. You could compute the length of the first row and the check all the other rows:

isMatrix []          = True
isMatrix (row1:rows) = allOfLength (length row) rows
   where
   allOfLength n rows = ....

Alternatively, compute the lengths of all the rows in advance using map length, and then check if the resulting list is formed by the same number, repeated:

isMatrix mat = allEqual (map length mat)
   where
   allEqual lengths = ....

Upvotes: 2

Related Questions