Pei Chuang
Pei Chuang

Reputation: 67

Card Suit Haskell

I have define the Card

module Card (Suit(..), Rank(..), Card(..)) where
import Data.List

data Suit = Club | Diamond | Heart | Spade
          deriving (Eq, Ord, Bounded, Enum)

suitchars = "CDHS"

data Rank =
    R2 | R3 | R4 | R5 | R6 | R7 | R8 | R9 | R10 |
    Jack | Queen | King | Ace
        deriving (Eq, Ord, Bounded, Enum)

rankchars = "23456789TJQKA"

data Card = Card {suit::Suit, rank::Rank}
          deriving (Eq, Bounded)

instance Ord Card where
    compare (Card s1 r1) (Card s2 r2) =
        let suitorder = compare s1 s2
        in  if suitorder == EQ then compare r1 r2 else suit order

and I try to use

getSuit:: [Card] -> Suit
getSuit [Card s r] = Suit [Card s r]

to get my suit of cards, but it doesnt work, also i have a pair of cards list

allCards :: [Card]
allCards = [Card suit rank | suit <- [Club .. Spade],  rank <- [R2 .. Ace]]

cardPair :: [[Card]]
cardPair = [[c1, c2] | c1 <- allCards, c2 <- allCards, c1 < c2 ]

now i want to move out or just keep the Pair of cards from cardPair, that contains that suit of cards, but i got problems

Upvotes: 0

Views: 883

Answers (2)

So, if I get it right, when given a list of pairs of cards, you want to keep only those pairs that have the same suit. OR only those pairs that have different suits.

First, since the name of the function is cardPairs and not cardLists, I suggest you use tuples instead of lists.

cardPair :: [(Card,Card)]
cardPair = [(c1, c2) | c1 <- allCards, c2 <- allCards, c1 < c2 ]

After that, you can apply a filter to the resulting list, filtering on either equality or inequality of the suits of c1 and c2. (I guess that's what you intend to use your getSuit function for). You use fst and snd to get the first and second element of the tuple, respectively.

Regarding getSuit, take a look at your definition:

getSuit  :: [Card] -> Suit
getSuit [Card s r] = Suit [Card s r]

The type definition of the function says [Card s r] is a list of Cards. I think the type should be

getSuit :: Card -> Suit

Upvotes: 0

chi
chi

Reputation: 116174

Regarding:

getSuit:: [Card] -> Suit
getSuit [Card s r] = Suit [Card s r]

Several errors appear above:

First, Suit is a type, not a value. So, you can not "return" it: ... = Suit ... is not correct. Note that the pattern matching done in

getSuit [Card s r] = ...

is already binding s to the suit and r to the rank. So, one could write instead

getSuit:: [Card] -> Suit
getSuit [Card s r] = s

This will pass type checking, but will trigger a non exhaustive pattern matching" warning if you enable warnings. The problem is that getSuit takes a [Card] as an input, which means a list of cards. The warning tells us that the function deinition covers the case in which the list contains exactly one card, but will fail if called with a list of two cards or more, or even with an empty list of cards.

Maybe you actually want the following instead:

getSuit:: Card -> Suit
getSuit (Card s r) = s

Here, no lists are involved.

Upvotes: 1

Related Questions