Haskell卡牌开发:更简洁的卡牌数据类型构造方法咨询
更简洁的Haskell卡牌花色-颜色关联实现
你的核心问题在于生成了大量不必要的无效组合再过滤,其实颜色完全由花色唯一确定,完全可以跳过“全组合+过滤”的步骤,直接生成合法卡牌。
优化方案
- 简化花色转颜色的函数:用模式匹配替代
any判断,更直观且高效(枚举类型的模式匹配是编译期优化的) - 直接生成合法卡牌:通过列表推导式,遍历所有点数和花色,直接推导对应颜色并构造Card,一步到位
优化后的完整代码
module Deck (Suit,Color,Rank,Card,Deck, makeCards) 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] -- 用模式匹配直接映射花色到颜色,比any判断更简洁高效 findColorForSuit :: Suit -> Color findColorForSuit Diamonds = Red findColorForSuit Hearts = Red findColorForSuit Spades = Black findColorForSuit Clubs = Black -- 直接生成所有合法卡牌,无需中间过滤步骤 makeCards :: Deck makeCards = [ Card r s (findColorForSuit s) | r <- [minBound :: Rank .. maxBound :: Rank] , s <- [minBound :: Suit .. maxBound :: Suit] ]
关键改进点
- 去掉冗余步骤:不再生成包含错误颜色的无效组合,直接为每个(rank, suit)生成对应颜色的Card,避免了过滤操作
- 模式匹配更清晰:
findColorForSuit用模式匹配明确列出每个花色对应的颜色,可读性远高于原有的any判断逻辑 - 代码更简洁:去掉了
cardCombinations、cardsWithColors、makeCard这些多余的中间函数,逻辑链更短
内容的提问来源于stack exchange,提问作者Martin Fahy
相关产品推荐
相关产品推荐

