通过选择许多其他数据类型之一表示的数据类型

时间:2016-09-09 01:51:22

标签: haskell types algebraic-data-types

我正在尝试为爆炸小猫的玩具实施生成一个套牌。

说我有以下类型:

if (departureDate <= arrivalDate) {
   alert ("You must make sure your departure is before your arrival!);
} 

和甲板发生器功能如下:

data ActionCard = Skip 
  | Attack 
  | Shuffle 
  | Nope 
  | Future 
  | Defuse 
  | Favor
  deriving Enum

data BasicCard = TacoCat 
  | MommaCat 
  | Catermelon 
  | BearCat 
  | PotatoCat 
  | BikiniCat 
  | RainboRalphingCat
  deriving Enum

data Card = ActionCard | BasicCard | BombCard

type Deck = [Card]

这失败了:

generateDeck :: Int -> Deck
generateDeck players = (concat (map (replicate 5) [TacoCat ..])) 
  ++ (replicate 2 Nope)
  ++ (replicate 4 Skip)
  ++ (replicate 4 Attack)
  ++ (replicate 4 Shuffle)
  ++ (replicate 4 Future)
  ++ (replicate 1 Defuse)
  ++ (replicate 4 Favor)
  ++ (replicate (players + 1) BombCard)

(以及其他非基本卡的类似错误)

这在一个级别上有意义,因为Couldn't match expected type ‘[BasicCard]’ with actual type ‘a7 -> [a7]’ Probable cause: ‘replicate’ is applied to too few arguments In the first argument of ‘(+)’, namely ‘replicate (length $ _players state)’ In the second argument of ‘(++)’, namely ‘(replicate (length $ _players state) + 1 BombCard)’ 返回(concat (map (replicate 5) [TacoCat ..])),但是我希望函数签名强制使用更通用的类型?

如何允许[BasicCard]成为CardActionCardBasicCard

1 个答案:

答案 0 :(得分:4)

data Card = ActionCard | BasicCard | BombCard

这将创建一个新的数据类型Card,其中包含三个名为ActionCardBasicCardBombCard的构造函数。这与名为ActionCardBasicCard的其他两种数据类型无关;类型和构造函数的名称空间是不同的。

您要做的是将Card定义为包含ActionActionCard Basic或{{{BasicCard的{​​{1}} 1}}:

BombCard

然后你可以通过将每种卡片类型包装在正确的构造函数中来创建data Card = Action ActionCard | Basic BasicCard | BombCard

Deck