Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell:如何生成两种简单代数数据类型的笛卡尔积_Haskell_Cartesian Product_Algebraic Data Types - Fatal编程技术网

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张牌组成的原始牌组。我相

我在学习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张牌组成的原始牌组。我相信有一种巧妙的方法可以做到这一点,但我能想到的是:

 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]