2014-09-11 118 views
0

我已经定义了卡牌西服哈斯克尔

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

*“它不工作[...]我有问题”*。什么不行?什么问题?编译器错误?运行时异常?你的猫着火了吗?此外,ThreeFX提供了一个不错的'cardPair'函数[上次](http://stackoverflow.com/questions/25600917/haskell-pair-two-cards),但它与你当前的问题有什么关系? (其实,你的帖子无论如何都缺少一个问题) – Zeta 2014-09-11 11:59:33

回答

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 
1

关于:出现上述情况

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

几个错误:

首先,Suit是一个类型,而不是一个值。所以,你不能“返回”它:... = Suit ...是不正确的。需要注意的是图案

getSuit [Card s r] = ... 

匹配完成已经结合s的西装r到基层。所以,一个可以写,而不是

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

这将通过类型检查,但会触发非详尽模式匹配”如果启用了警告的警告,但问题是,getSuit需要[Card]作为输入,这意味着名单警告告诉我们,功能定义涵盖列表中只包含一张卡片的情况,但如果使用两张或更多卡片的列表或者甚至是一张空的卡片列表进行调用,将会失败。也许你实际上想要以下内容:

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

在这里,不涉及任何列表。