在Haskell使用列表理解的完整甲板

Tob*_*rdt 1 haskell

我对Haskell(和编程)很陌生.我的任务是定义一个功能,返回一整套卡(又名52卡).试图将我的思维过程包含在代码旁边的注释中.

- 我定义的值

data Suit = Club | Diamond | Heart | Spade  deriving (Show, Enum)

data Value = Two | Three | Four | Five | Six | Seven
          | Eight | Nine | Ten | Jack | Queen
          | King | Ace  deriving (Show, Enum) 

type Card = (Suit, Value)  -- A card must have a suit and a value
type Deck = [Card]        -- A deck consists of a list of cards

fullDeck :: Deck    -- My function is supposed to consist of a deck
fullDeck = [(suit, value) | suit <- [Club..Spade], value <- [Two..Ace]]  -- Tried my luck using ''list comprehensions''. Is it necessary to type [Club..Spade] or does it work for just [Club..] as well? 
Run Code Online (Sandbox Code Playgroud)

我的代码不会加载.我得到的错误:

beginner.hs:11:62: error:
    A section must be enclosed in parentheses thus: (Two.. Ace)
   |
11 | fullDeck = [(suit, value) | suit <- [Club..Spade], value <- [Two..Ace]]
Run Code Online (Sandbox Code Playgroud)

无论我如何尝试解决它,都会出现一些新的错误,所以我显然正在做一些我无法找到的重大失败.

另外我很好奇如何确保我的牌组中只有52张牌,因为目前我的列表中包含无限量的牌?

Wil*_*sem 6

您忘记在数据构造函数(如和)和运算符之间使用空格.如果不这样做,Haskell会将此视为用于例如合格导入的点.ClubSpade..

以下作品:

[(suit, value) | suit <- [Club .. Spade], value <- [Two .. Ace]]
--                            ^  ^                     ^  ^
Run Code Online (Sandbox Code Playgroud)

这会产生预期的:

Prelude> [(suit, value) | suit <- [Club .. Spade], value <- [Two .. Ace]]
[(Club,Two),(Club,Three),(Club,Four),(Club,Five),(Club,Six),(Club,Seven),(Club,Eight),(Club,Nine),(Club,Ten),(Club,Jack),(Club,Queen),(Club,King),(Club,Ace),(Diamond,Two),(Diamond,Three),(Diamond,Four),(Diamond,Five),(Diamond,Six),(Diamond,Seven),(Diamond,Eight),(Diamond,Nine),(Diamond,Ten),(Diamond,Jack),(Diamond,Queen),(Diamond,King),(Diamond,Ace),(Heart,Two),(Heart,Three),(Heart,Four),(Heart,Five),(Heart,Six),(Heart,Seven),(Heart,Eight),(Heart,Nine),(Heart,Ten),(Heart,Jack),(Heart,Queen),(Heart,King),(Heart,Ace),(Spade,Two),(Spade,Three),(Spade,Four),(Spade,Five),(Spade,Six),(Spade,Seven),(Spade,Eight),(Spade,Nine),(Spade,Ten),(Spade,Jack),(Spade,Queen),(Spade,King),(Spade,Ace)]
Run Code Online (Sandbox Code Playgroud)

我们也可以 - 比如@Amalloy说 - 制作类型Bounded,然后写成:

data Suit = Club | Diamond | Heart | Spade  deriving (Show, Enum, Bounded)

data Value = Two | Three | Four | Five | Six | Seven
          | Eight | Nine | Ten | Jack | Queen
          | King | Ace  deriving (Show, Enum, Bounded)

fullDeck :: Deck    -- My function is supposed to consist of a deck
fullDeck = [(suit, value) | suit <- [minBound ..], value <- [minBound ..]]
Run Code Online (Sandbox Code Playgroud)

或者我们可以定义一个辅助值:

boundedAll :: (Bounded a, Ord a) => [a]
boundedAll = [minBound ..]
Run Code Online (Sandbox Code Playgroud)

然后把它写成:

fullDeck :: Deck
fullDeck = (,) <$> boundedAll <*> boundedAll
Run Code Online (Sandbox Code Playgroud)