如何在 Haskell 中融合两个相同类型的枚举?

How can I fuse two enums of the same type in Haskell?

我对 Haskell 还是很陌生,我很好奇如何将两个 Hand 合并在一起,以便第一只手放在二手。我希望它是一个中缀运算符,即 (<+)。这里有一些代码可以帮助你。本质上,我的意思是我需要以某种方式帮助 "append" 两只手。

data Rank = Numeric Integer | Jack | Queen | King | Ace
            deriving (Eq, Show)

data Suit = Hearts | Spades | Diamonds | Clubs
            deriving (Eq, Show)

data Card = Card Rank Suit
            deriving (Eq, Show)

data Hand = Empty | Add Card Hand
            deriving (Eq, Show)

(<+) :: Hand -> Hand -> Hand
(<+) Empty Empty = Empty
(<+) h Empty     = h
(<+) Empty h     = h
(<+) h1 h2       = h1 ++ h2

到目前为止,我已经尝试了 mergeappendmappend++,如上所示。

您需要对其中一只非空手牌进行模式匹配,以便您可以访问其中的牌。

(<+) :: Hand -> Hand -> Hand
Empty <+ h = h
h <+ Empty = h
(Add c rest1) <+ h = Add c (rest1 <+ h)

严格来说,你不需要h <+ Empty = h,因为第三条规则可以在你达到Empty <+ h后重建这手牌。但是第二条规则节省了一些计算量。

您不能使用 ++ 等。因为其中 none 是为 Hand 定义的。但是,正如您在对上一个问题的评论中指出的那样,Hand 所做的只是重新实现内置列表类型。您可以通过定义新类型来利用它。

newtype Hand = Hand [Card]

然后

(<+) :: Hand -> Hand -> Hand
(Hand h1) <+ (Hand h2) = Hand (h1 ++ h2)