我正在学习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
Run Code Online (Sandbox Code Playgroud)
现在我想创建一张52张牌的原始牌组.我确信有一种光滑的方式可以做到,但我能想到的只有:
pristineDeck = [Card Ace Hearts, Card Two Hearts, ...]
Run Code Online (Sandbox Code Playgroud)
我可以让Haskell为我生成这个列表吗?
C. *_*ann 10
列表推导是一种非常整洁的语法.如果你得到Enum的Rank与Suit你可以很简单地表达出来:
pristineDeck = [ Card rank suit | suit <- [Hearts .. Clubs], rank <- [Ace .. King] ]
Run Code Online (Sandbox Code Playgroud)
如果你想知道为什么我suit和rank按不同的顺序,首先是因为订单的Card构造函数使用,而后者则是得到结果列表的顺序-升序西装在一起.
更一般地说,或者当单个列表理解变得过于庞大时,笛卡尔积恰好是Monad列表实例给出的行为.以下等同于上面的列表理解:
pristineDeck = do suit <- [Hearts .. Clubs]
rank <- [Ace .. King]
return $ Card rank suit
Run Code Online (Sandbox Code Playgroud)
作为一个其他的小点,保存自己的记忆的麻烦什么顺序Suit值在,导出Bounded以及将使写[minBound .. maxBound]枚举任何类型的所有值与两个实例Enum和Bounded.
有几种方法可以做到这一点,不同程度的魔法.
首先,由于您的类型的构造函数都没有参数,您可以Enum为它们派生.这将允许您编写例如[Ace..King]以获取所有卡的列表.
其次,列表推导是形成从多个其他列表中绘制的项目列表的好方法.试试这个:
[x + y | x <- [100,200,300], y <- [1,2,3]]
Run Code Online (Sandbox Code Playgroud)
这应该为您提供应用于您的示例所需的工具.
| 归档时间: |
|
| 查看次数: |
566 次 |
| 最近记录: |