Haskell:如何生成两种简单代数数据类型的笛卡尔积
我在学习Haskell,所以我在写一些简单的纸牌游戏。我定义了一些数据类型:Haskell:如何生成两种简单代数数据类型的笛卡尔积,haskell,cartesian-product,algebraic-data-types,Haskell,Cartesian Product,Algebraic Data Types,我在学习Haskell,所以我在写一些简单的纸牌游戏。我定义了一些数据类型: data Rank = Ace|Two|Three|Four|Five|Six|Seven|Eight|Nine|Ten|Jack|Queen|King deriving (Eq,Show,Ord) data Suit = Hearts|Spades|Diamonds|Clubs deriving (Show) data Card = Card Rank Suit 现在我想创建一个由52张牌组成的原始牌组。我相
data Rank = Ace|Two|Three|Four|Five|Six|Seven|Eight|Nine|Ten|Jack|Queen|King deriving (Eq,Show,Ord)
data Suit = Hearts|Spades|Diamonds|Clubs deriving (Show)
data Card = Card Rank Suit
现在我想创建一个由52张牌组成的原始牌组。我相信有一种巧妙的方法可以做到这一点,但我能想到的是:
pristineDeck = [Card Ace Hearts, Card Two Hearts, ...]
我能让Haskell为我生成这个列表吗?列表理解是一个非常简洁的语法。如果在
Rank
和Suit
上导出Enum
,则可以非常简单地表示为:
pristineDeck = [ Card rank suit | suit <- [Hearts .. Clubs], rank <- [Ace .. King] ]
另一个小问题是,为了省去记忆
套装
值的顺序的麻烦,派生Bounded
也将允许编写[minBound..maxBound]
要使用Enum
和Bounded
实例枚举任何类型的所有值,有几种方法可以实现这一点,可以使用不同数量的向导
首先,由于类型的构造函数都没有参数,因此可以为它们派生Enum
。这将允许您编写例如[Ace..King]
以获得所有卡的列表
其次,列表理解是一种从多个其他列表中提取项目列表的好方法。试试这个:
[x + y | x <- [100,200,300], y <- [1,2,3]]
[x+y | xAlp在告诉您派生枚举时是正确的
>data Rank = Ace|Two|Three|Four|Five|Six|Seven|Eight|Nine|Ten|Jack|Queen|King deriving (Eq,Show,Ord,Enum)
>data Suit = Hearts|Spades|Diamonds|Clubs deriving (Show,Enum)
现在:
要获得两个列表的排列,可以使用列表理解:
>[[x,y]|x<-[1..2],y<-[2..5]]
[[1,2],[1,3],[1,4],[1,5],[2,2],[2,3],[2,4],[2,5]]
[[x,y]|让你的类型派生出“Enum”类型类(只需将Enum放在Show
旁边就可以了)。这三个类型:等级、套装和卡片。P.S.你要找的不是叉积,它涉及到三维向量。你可能指的是“笛卡尔积”。@BenMillwood My bad…”SQL cross join“+“笛卡尔积”+中的阶数physics@BenMillwood:最好还是稳妥一点,像数学家一样——把每件事都称为“积”,并依靠上下文来消除歧义。也许可以称之为“张量积”"如果你觉得很慷慨。@C.A.McCann:你有一个总数吗?取而代之的是一个副产品!就我个人而言,我不会为套装
类型派生Enum
,只需在理解中写出完整的列表。套装没有自然的顺序,依我看,所以省略号语法很混乱。我还会在站姿。[minBound..maxBound]
表明您正在枚举所有变体,即使没有自然顺序。@AlfonsoVillén:谢谢。愚蠢、糟糕、没有好的颈部疼痛句法角案例…Card[minBound..maxBound][minBound..maxBound]
@Tinctorius:那就行了!但在这种情况下,我实际上认为列表理解更具可读性。更有用的是我在经过调整的前奏曲中定义的枚举=[minBound..maxBound]
。它正好适合这种用途。
>enumFrom Ace
[Ace,Two,Three,Four,Five,Six,Seven,Eight,Nine,Ten,Jack,Queen,King]
>[[x,y]|x<-[1..2],y<-[2..5]]
[[1,2],[1,3],[1,4],[1,5],[2,2],[2,3],[2,4],[2,5]]
>[x + y|x<-[1..2],y<-[2..5]]
[3,4,5,6,4,5,6,7]