2

The following is my factorial function:

factorial :: Integer -> Integer
factorial n
  | n < 0 = -1
  | n > 0 = n * factorial (n-1)
  | n == 0 = 1

I guess, I covered all the cases (+ve, -ve, 0). When I try to load above code, I am getting following warnings. Why am I getting warnings?

Prelude> :load Fact.hs 
[1 of 1] Compiling Main             ( Fact.hs, interpreted )

Fact.hs:2:1: Warning:
   Pattern match(es) are non-exhaustive
In an equation for ‘factorial’: Patterns not matched: _
Ok, modules loaded: Main.
Chris Martin
  • 30,334
  • 10
  • 78
  • 137
Hari Krishna
  • 3,658
  • 1
  • 36
  • 57

3 Answers3

4

This is ghc being conservative. Your code has all possible values of "n" covered, but ghc isn't smart enough to prove that, so it warns you.

Try replacing your "n < 0" with "otherwise" and putting it at the end. This is defined as

otherwise = True

That will become the catch-all case which will make ghc comfortable.

Paul Johnson
  • 17,438
  • 3
  • 42
  • 59
  • That is to say, add a case `| otherwise = error "The impossible happened."` Or something along those lines. – AJF Apr 10 '16 at 09:40
  • I think Paul means to handle one of the legitimate cases with a catch-all case. I would [stay away from `error` if possible](http://programmers.stackexchange.com/questions/252977/cleanest-way-to-report-errors-in-haskell). – zoul Apr 10 '16 at 09:42
2

The compiler can't tell that all inputs match at least one of three guards.

Here's a suggestion to fix that and also remove some repetition:

factorial :: Integer -> Integer
factorial n = case compare n 0 of
  LT -> -1
  GT -> n * factorial (n-1)
  EQ -> 1
Chris Martin
  • 30,334
  • 10
  • 78
  • 137
1

I think the compiler isn’t smart enough to know that covering the three cases is exhaustive for the particular type. Simply use the otherwise pattern in the third rule instead of zero?

(And by the way, factorial is usually only defined for positive integers, so I don’t know how much your negative branch is correct.)

zoul
  • 102,279
  • 44
  • 260
  • 354