卡套装Haskell

时间:2014-09-11 10:26:43

标签: haskell

我已经定义了卡

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

我尝试使用

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

得到我的西装卡,但它不起作用,我也有一对卡片列表

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

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

现在我想搬出或者只是保留来自cardPair的那对卡片,其中包含那套卡片,但我遇到了问题

2 个答案:

答案 0 :(得分:1)

关于:

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

上面出现了几个错误:

首先,Suit是一种类型,而不是一种值。所以,你不能&#34;返回&#34;它:... = Suit ...不正确。请注意,模式匹配在

中完成
getSuit [Card s r] = ...

已经将s绑定到套装,r绑定到等级。所以,可以写一个

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

这将通过类型检查,但会触发非穷举模式匹配&#34;如果启用警告则发出警告。问题是getSuit需要[Card]作为输入,这意味着卡片列表。警告告诉我们,功能定义涵盖了列表中只包含一张卡的情况,但如果使用两张或更多卡的列表调用,或者甚至使用空卡列表,则会失败。

也许你真的想要以下内容:

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

此处不涉及任何列表。

答案 1 :(得分:0)

所以,如果我做对了,当给出一对卡片列表时,你只想保留那些具有相同套装的对。或者只有那些有不同套装的对。

首先,由于函数的名称是cardPairs而不是cardLists,我建议您使用元组而不是列表。

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

之后,您可以将filter应用于结果列表,过滤c1和c2套装的相等或不等式。 (我想这就是你打算使用你的getSuit功能)。您使用fstsnd分别获取元组的第一个和第二个元素。

关于getSuit,请查看您的定义:

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

该函数的类型定义说[Card s r]是一个卡列表。我认为类型应该是

getSuit :: Card -> Suit