0

I'm trying to prove that the numbers of the form p_1 * ... * p_k + 1 are not all prime, and to do this, I have written this code

sieve :: [Integer] -> [Integer]
sieve (0:xs) = sieve xs
sieve (x:xs) = x : sieve (mark x xs)
 where
 mark :: Integer -> [Integer] -> [Integer]
 mark n (y:ys)
  | rem y n == 0 = 0 : (mark n ys)
  | otherwise = y : (mark n ys)

checkPrime' :: Integer -> Bool
checkPrime' n = elem n (sieve [n])

listPrimeFromTo' :: Integer -> Integer -> [Integer]
listPrimeFromTo' k n = sieve [k..n]

checkEulerPrimes = forall [(product xs) + 1|  n <- [2..], let xs = listPrimeFromTo' 2 n] checkPrime'

I get this exception:

*** Exception: Ch3.hs:(11,2)-(13,31): Non-exhaustive patterns in function mark

However, in the definition of the function mark, I use otherwise, so how is it possible that there are cases which the definition of the function does not specifies any rule for that. I mean I thought using the keyword otherwise makes sure that there is no non-exhausted patterns.

Our
  • 986
  • 12
  • 22
  • 4
    Because the `otherwise` is a *guard* of a specific pattern. What if one writes `mark 3 []`? Then which clause should fire? The same with `sieve` itself: there is no clause that describes what to do in case of an empty list. – Willem Van Onsem Aug 02 '18 at 16:09
  • Well, that makes sense. After all, in order to say `let x be in a set A`, first you need to show `A is not empty`. – Our Aug 02 '18 at 16:12
  • 1
    I strongly suggest you turn on warnings using `-Wall`. Not only that would catch the missing case at compile time, but it also will report that `[]` is the missing case. – chi Aug 02 '18 at 17:27

1 Answers1

2

otherwise is indeed a guard which always succeeds; but guards are only considered when the associated pattern already matches. So, in

foo (x:xs) | otherwise = bar

we will only see bar as the result when the argument to foo matches the pattern x:xs. The analogous pattern to otherwise is _, which always matches and doesn't bind any new variables, so:

foo (x:xs) | otherwise = bar
foo _ = baz

would never throw an unmatched pattern exception.

Daniel Wagner
  • 145,880
  • 9
  • 220
  • 380