Function 如何在Haskell中将枚举列表转换为另一种类型的枚举?

Function 如何在Haskell中将枚举列表转换为另一种类型的枚举?,function,haskell,list-comprehension,haskell-platform,Function,Haskell,List Comprehension,Haskell Platform,我正在尝试编写一个函数来创建一副完整的卡片(52张,没有小丑)。我对此还是新手,我认为某种列表理解是我需要做的,但我不太知道如何编写它(请参见createHandFromList函数)。我也猜它需要递归,这样它才能继续运行。无论如何,到目前为止,我的代码看起来是这样的,任何帮助和建议都将一如既往地非常感谢 data Card = Card Rank Suit deriving (Eq, Show) data Rank = Numeric Integer | Jack | Queen

我正在尝试编写一个函数来创建一副完整的卡片(52张,没有小丑)。我对此还是新手,我认为某种列表理解是我需要做的,但我不太知道如何编写它(请参见
createHandFromList
函数)。我也猜它需要递归,这样它才能继续运行。无论如何,到目前为止,我的代码看起来是这样的,任何帮助和建议都将一如既往地非常感谢

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

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

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

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

fullDeck :: Hand
fullDeck = createHandFromList (suitedCardList Clubs ++
                suitedCardList Diamonds ++
                suitedCardList Hearts ++
                suitedCardList Spades)

suitedCardList :: Suit -> [Card]
suitedCardList s = [Card (Numeric 2) s, Card (Numeric 3) s,
                    Card (Numeric 4) s, Card (Numeric 5) s,
                    Card (Numeric 6) s, Card (Numeric 7) s,
                    Card (Numeric 8) s, Card (Numeric 8) s,
                    Card (Numeric 10) s, Card Jack s,
                    Card Queen s, Card King s, Card Ace s]

createHandFromList :: [Card] -> Hand -> Hand
createHandFromList [c:cs] h = [Add card h | card <- c]
数据卡=卡片等级套装
推导(等式,显示)
数据等级=数字整数|杰克|女王|国王|王牌
推导(等式,显示)
数据套装=红桃|黑桃|钻石|梅花
推导(等式,显示)
数据手=空|添加卡片手
推导(等式,显示)
全副武装
fullDeck=createHandFromList(适用的卡片列表)++
suitedCardList钻石++
suitedCardList红心++
suitedCardList(黑桃)
suitedCardList::套装->[卡片]
suitedCardList s=[卡(数字2)s,卡(数字3)s,
卡片(数字4)s、卡片(数字5)s、,
卡片(数字6)s、卡片(数字7)s、,
卡片(数字8)s,卡片(数字8)s,
卡(数字10)s、卡插孔s、,
卡片女王s、卡片国王s、卡片王牌s]
createHandFromList::[Card]->Hand->Hand

createHandFromList[c:cs]h=[Add card h | card此代码存在多个问题。首先,您在
createHandFromList
的定义中将
[c:cs]
用作模式。但是,这是一个语法错误:在模式匹配中,语法为
(c:cs)
。这给出了以下代码:

createHandFromList::[Card]->Hand->Hand
createHandFromList(c:cs)h=[添加卡片h |卡片手->手
--将卡“c”添加到(createHandFromList cs h)的结果中
createHandFromList(c:cs)h=添加c(createHandFromList cs h)
--如果没有更多的牌可供添加,则返回手牌“h”
createHandFromList[]h=h

还有一个小小的简化,我想说。(这要归功于@Khuldraeseth na'Barya,他在评论中写道。)让我们看看
Hand
的可能值:

  • Empty
  • addcard1空
  • addcard2(addcard1为空)
  • addcard3(addcard2(addcard1为空))
  • 等等
这看起来就像是一张
卡片
s!的列表,结果是
[Card]
的类型是同构的。在pseudo Haskell中:

数据手=空|添加卡片手
数据[卡]=[]|:卡[卡]

因此,如果您将
Hand
表示为类似
newtype Hand=Hand{getCards::[Card]}
,那么您应该能够用列表理解替换递归。这留给读者作为练习。

另外,您的
suitedCardList
函数可以更容易地写成
[Card v s | v@Alex查看您的代码后,我确实发现您的
fullDeck
函数有一个小问题:
createHandFromList
需要两个参数,但您只为其提供了一个参数。这可能是您的问题的原因吗?要回答您的Q标题,而不是正文,请使用
派生Enum
和然后使用
fromnum
toEnum
。回滚编辑,因为它消除了
[c:cs]
的问题,而不更新错误。代码存在多个问题;不要按照注释中指出的方式编辑问题。关闭问题,或者(因为尚未发布答案),简化它以关注仍然存在的问题。这个问题可以简化。看看列表声明:
data[]a=[]a:[a]
。从中得到一个具体的类型:
[Card]=[]Card:[Card]
。看起来很熟悉吗?你的
手上的
类型只不过是一张
卡的列表。
BlackJack.hs:107:21: error:
    • Couldn't match expected type ‘Card’ with actual type ‘[[Card]]’
    • In the pattern: c : cs
      In the pattern: [c : cs]
      In an equation for ‘createHandFromList’:
          createHandFromList [c : cs] h = [Add card h | card <- c]
    |
107 | createHandFromList [c:cs] h = [Add card h | card <- c]     |                     ^^^^

BlackJack.hs:107:31: error:
    • Couldn't match expected type ‘Hand’ with actual type ‘[Hand]’
    • In the expression: [Add card h | card <- c]
      In an equation for ‘createHandFromList’:
          createHandFromList [c : cs] h = [Add card h | card <- c]
    |
107 | createHandFromList [c:cs] h = [Add card h | card <- c]     |