-1

Im trying to write a function that takes in list of Cards and gives me back all the rank values. Im getting the problem of Non-exhaustive patterns in function and I can't fix it

data Card = Card Suit Rank
          deriving (Show, Bounded, Read)

data Suit = Red
          | Black
          deriving (Show, Enum, Bounded, Read)

data Rank = Ace   
          | Two
          | Three
          | Four
          | Five
          | Six
          | Seven
          | Eight
          | Nine
          | Ten
          deriving (Show, Enum, Bounded, Read)

handValue :: [Card] -> [Int]
handValue [Card s r] 
    | (length [Card s r]) < 0 = (fromEnum (r) + 1) : handValue (tail [Card s r])
    | otherwise               = []

What Can I do to counter this problem?

maggibaggi
  • 21
  • 2
  • 1
    It's difficult to answer this question because `handValue` has other issues that will persist even if this problem is solved. For instance, `[Card s r]` is an element containing exactly one card. `tail [Card s r]` will always be `[]`. `length [Card s r]` will always be `1` and, in any event, can never be `< 0`. If you want to match on a list, think "What do I do with the empty list? What do I do with x cons xs?" In other words, `handValue [] = []; handValue (Card s r : cards) = ???`. – Rein Henrichs Sep 26 '18 at 16:09
  • 1
    I think the fundamental confusion here is that `handValue [Card s r]` does not match on any list of cards, it matches on a list of exactly one element. This is why the pattern is incomplete. – Rein Henrichs Sep 26 '18 at 16:11

1 Answers1

2

In:

handValue :: [Card] -> [Int]
handValue [Card s r] 

you're defining the function for the case of a length 1 list passed as the first argument. You haven't defined the function for the other cases - length less than 1 or length greater than 1.

[Card s r] is a pattern that matches the length 1 list and unpacks the only value in it in to s and r. It looks like you want to do something more like:

handValue cards
| (length cards) < 0 = ...
| otherwise          = []

but this doesn't quite make sense since the length of a list can never be less than 0.

Perhaps you mean something more like:

handValue [] = []
handValue (Card s r):cards = (fromEnum r + 1) : handValue cards

which pattern matches the empty list and the non-empty list which should be exhaustive.

Jean-Paul Calderone
  • 47,755
  • 6
  • 94
  • 122