Junwen Xie
Junwen Xie

Reputation: 15

Haskell *** Exception: Prelude.head: empty list

this function is to find out how many elements in list A is smaller than the smallest element in list B

every time the recursion happens the length list of A is reduce until emepty.

however... it only return the Exception: Prelude.head: empty list not even a 0..

why it is happened?

compareSmall::[Card] -> [Card] -> Int
compareSmall [] _ = 0
compareSmall _ [] = 0
compareSmall (x:xs) (y:ys) =         
        if   rank  (head tnt1) < rank (head tnt2)   then         
            1 + compareSmall (tail tnt1) (tnt2)      
        else if  rank (head (tail tnt1)) == rank (head tnt2) then       
            0 + compareSmall (tail tnt1) (tnt2)       
        else 
            0 + compareSmall (tail tnt1) (tnt2)
                    where tnt1 = rankCard (x:xs)
                          tnt2 = rankCard (y:ys)

Upvotes: 1

Views: 1344

Answers (1)

Tehnix
Tehnix

Reputation: 2040

Why

Your problem lies in rankCard returning an empty list and thus tnt1 or tnt2 is [] at some point. You then get the error when you do head tnt1, because head is a partial function, and will throw an exception on an empty list instead of a Maybe.

This is happening in the call else if rank (head (tail tnt1)) == rank (head tnt2) then, specifically (head (tail tnt1)) giving an error when tnt1 is a list containing 1 element.

Fixing it

It seems your second if-statement is not needed since you never modify your tnt2 list, so it will be caught the final else by letting the recursion run one more time and not throw any errors. Your code could just be

compareSmall :: [Card] -> [Card] -> Int
compareSmall [] _ = 0
compareSmall _ [] = 0
compareSmall a b  =
  if rank (head tnt1) < rank (head tnt2)   then
    1 + compareSmall (tail tnt1) b
  else
    0 + compareSmall (tail tnt1) b
  where
    tnt1 = rankCard a
    tnt2 = rankCard b

Side-note: Haskell has syntax for keeping the whole list when you pattern match it, so you could do

compareSmall a@(x:xs) b@(y:ys) =
  ...
  where
    tnt1 = rank a
    tnt2 = rank b

if you ever need that.

Upvotes: 1

Related Questions