我在Haskell中创建了一个纸牌游戏,我需要知道每种花色的纸牌颜色。
现在,我使用cardCombinations
构造花色、排名和颜色的所有可能组合,然后使用cardWithColors
过滤结果以构造Deck
要求是我希望套装具有正确的关联颜色:方块红桃和黑桃梅花是黑色的。
有没有可能有一种更简洁的方式来表达这种逻辑,而不是先构造所有组合,然后再过滤它们?
module Deck (Suit,Color,Rank,Card,Deck) where
data Color = Red | Black deriving (Eq,Enum,Show,Ord,Bounded)
data Suit = Clubs | Diamonds | Hearts | Spades deriving (Eq,Ord,Enum,Bounded,Show)
data Rank = Two | Three | Four | Five | Six | Seven | Eight | Nine | Ten
| Jack | Queen | King | Ace deriving (Eq,Ord,Enum,Bounded,Show)
data Card = Card { rank :: Rank
, suit :: Suit
, color :: Color } deriving (Eq,Ord,Bounded,Show)
type Deck = [Card]
findColorForSuit :: Suit -> Color
findColorForSuit suit
| any (suit==) [Diamonds, Hearts] = Red
| any (suit==) [Spades, Clubs] = Black
cardCombinations = [(ranks, suits, colors) | ranks <- [minBound :: Rank .. maxBound :: Rank], suits <- [minBound :: Suit .. maxBound :: Suit], colors <- [minBound :: Color .. maxBound :: Color]]
cardsWithColors = filter (\(_,suit,color) -> (findColorForSuit suit) == color) cardCombinations
makeCard :: (Rank, Suit, Color) -> Card
makeCard (rank, suit, color) = Card rank suit color
makeCards :: Deck
makeCards = map makeCard cardsWithColors
我试着创建所有组合,然后根据过滤器 predicate 过滤结果,以确定如何将颜色与套装相关联。
2条答案
按热度按时间yks3o0rb1#
这些要求也被称为不变量,习惯上的做法是尽可能避免它们(使非法状态不可表示)。有时避免所有不变量确实很难和/或不实际,然而,在您的情况下,这真的很容易,因为每张卡的
Color
由Suit
唯一确定。除了color
字段,您可以将其定义为函数。这意味着每一张
Card
都是一张有效的牌,你可以构造所有可能的行列和花色组合。enxuqcxy2#
我会让
Card
只包含排名和花色,然后编写一个函数来 * 计算 * 颜色(通过使用findColourForSuit
,尽管如果使用单个模式匹配,而不是使用any
、==
和列表,这会更简单)。你不需要存储每一张牌的颜色,它是由你已经存储的花色所暗示的,就像我们不需要在每一张
Integer
上放置一个字段even :: Bool
;我们只存储整数的值,当我们需要知道它是奇数还是偶数时,我们计算它。