我正在 Haskell 中创建一个纸牌游戏,我需要知道每种花色的纸牌颜色。
现在我使用 cardCombinations
构建所有可能的花色、等级和颜色组合,然后使用 cardWithColors
过滤结果以构建 Deck
要求是我希望西装具有正确的相关颜色:方 block 、红心为红色,黑桃、梅花为黑色。
有没有比先构造所有组合然后过滤它们更简洁的方式来表达这个逻辑?
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
我尝试创建所有组合,然后根据过滤谓词过滤结果以确定如何将颜色与西装相关联。
最佳答案
这些要求也称为不变量,惯用的方法是尽可能避免它们(使非法状态不可表示)。有时避免所有不变量真的很难和/或不切实际,但是在您的情况下这真的很容易,因为每张牌的 Color
由 Suit
唯一确定.您可以将它定义为一个函数,而不是 color
字段。
data Card = Card { rank :: Rank, suit :: Suit }
deriving (..)
color :: Card -> Color
color card = findColorForSuit (suit card)
这意味着每张 Card
都是构造有效的 Card,您可以构造所有可能的点数和花色组合。
关于haskell - 构造此数据类型的更惯用的方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74539798/