haskell - 构造此数据类型的更惯用的方法是什么?

标签 haskell

我正在 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

我尝试创建所有组合,然后根据过滤谓词过滤结果以确定如何将颜色与西装相关联。

最佳答案

这些要求也称为不变量,惯用的方法是尽可能避免它们(使非法状态不可表示)。有时避免所有不变量真的很难和/或不切实际,但是在您的情况下这真的很容易,因为每张牌的 ColorSuit 唯一确定.您可以将它定义为一个函数,而不是 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/

相关文章:

arrays - Haskell 中的非整体数组

haskell - 在 Haskell 中如何说 A 类型的数据也是 B 类型?

list - 在Haskell中递归搜索记录属性并收集到列表中

haskell - Haskell 学院的代码共享

regex - Haskell 和正则表达式 - 为什么我的功能消除冗余空间不起作用?

haskell - 如何查看Monad Reader的代码?

haskell - isAlpha 和 isLetter 有什么区别?

haskell - 如何将函数调用的值存储到变量

generics - 如何使用 GHC.Generics 的 selName 函数?

haskell - 为什么ghci不识别inits函数