Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell non exhaustive patterns in function

Tags:

haskell

the following code compiles well but when i try to input helper 10 primes [] [] it gives me :Non-exhaustive patterns in function helper

primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]

eea :: Integer -> Integer -> (Integer, Integer, Integer)
eea 0 b = (0, 1, b)
eea a b = (y - b `div` a * x, x, g) where (x, y, g) = eea (b `rem` a) a

second :: (a, b, c) -> b
second (_, x, _) = x

chinese :: Integer -> [(Integer,Integer)] -> Integer
chinese n [] = 0
chinese n ((a,b):xs) = ((second(eea b (n `div`  b)) * (n `div`  b) )  * a) + chinese n (xs)

getN :: [(Integer,Integer)] -> Integer
getN [] = 1
getN ((x,y):xs) = y*(getN (xs))

chinese2 :: [(Integer,Integer)] -> Integer
chinese2 [] = 0
chinese2(x:xs) = chinese (getN (x:xs)) (x:xs)

chinese3 :: [(Integer,Integer)] -> Integer
chinese3 (x:xs) = if (chinese2(x:xs)) < 0 then chinese2 (x:xs) + (getN (x:xs)) else chinese2 (x:xs)

helper :: Integer -> [Integer] -> [Integer] -> [(Integer,Integer)] -> [Integer]
helper n [] (v) _ = []
helper n (x:y:xs) (v) (c:cs) = if (chinese3 (b:c:cs) == n) then (x:v) else helper n (xs) (x:v) ((n `mod` y,y):c:cs) where b =(n `mod` x,x)
like image 734
Fady Kamal Avatar asked Jan 05 '12 20:01

Fady Kamal


3 Answers

chinese3 has no case for the empty list.

helper lacks several more cases, including one where the second argument has one element.

like image 66
Fred Foo Avatar answered Nov 13 '22 11:11

Fred Foo


What you're trying to evaluate:

helper 10 primes   []  []

Your equations for helper:

helper n  []       (v) _      = ...
helper n  (x:y:xs) (v) (c:cs) = ...

Let's try to match the first equation:

  • n = 10 matches
  • [] = primes does not match

OK, let's try to match the second equation instead:

  • n = 10 matches
  • (x:y:xs) = primes matches, with
    • x = 2
    • y = 3
    • xs = [5, 7, 11, 13, ...]
  • v = [] matches
  • (c:cs) = [] does not match

So neither pattern matches. We have a pattern match failure.

like image 39
dave4420 Avatar answered Nov 13 '22 10:11

dave4420


Based on the first line of the definition of helper, it will match on an empty list ([]) in the second argument. Based on the second line, it will match on a list of at least two values in the second argument (x:y:xs). This leaves a single-item list unaccounted for.

EDIT

For the sake of simplicity, let's assume that primes is defined like this:

primes = [2, 3, 5]

Now when you evaluate this expression:

helper 10 primes [] []

Clearly it's the second part of the definition of helper that will get matched here (the first part would only match if primes were an empty list). Now based on the pattern for the second parameter (x:y:xs), we can see that x will be bound to 2, y will be bound to 3 and xs will be bound to [5]. In the definition of helper you are applying the function recursively using xs as the second argument. In other words, it looks something like this:

helper 10 [5] ...

Which case of the helper function will be used here? [5] is not an empty list, so not the first one. The second case? No, that case only matches against a list of at least two values (what value would y get bound to?). I hope you can now see that you have not accounted for when helper is called with a single item list as the second parameter (which in practice will happen any time you call helper with a list of an odd number of values in the second parameter).

like image 38
Daniel Pratt Avatar answered Nov 13 '22 10:11

Daniel Pratt