我是Haskell的新手,并且在使用递归制作一副牌时遇到了问题.
我有这些定义:
data Suit = Club | Diamond | Heart | Spade
data Value = Two | Three | Four | Five | Six | Seven
| Eight | Nine | Ten | Jack | Queen
| King | Ace
type Card = (Suit, Value)
type Deck = [Card]
instance Show Suit where
show Club = "Club"
show Diamond = "Diamond"
show Heart = "Heart"
show Spade = "Spade"
instance Show Value where
show Two = "Two"
show Three = "Three"
show Four = "Four"
show Five = "Five"
show Six = "Six"
show Seven = "Seven"
show Eight = "Eight"
show Nine = "Nine"
show Ten = "Ten"
show Jack = "Jack"
show Queen = "Queen"
show King = "King"
show Ace = "Ace"
Run Code Online (Sandbox Code Playgroud)
我正在尝试编写一个函数
makeDeck :: Deck
Run Code Online (Sandbox Code Playgroud)
它按照给出数据的顺序返回一张牌列表,所以(Club,Two - Ace),(Diamond,Two-Ace)等等.
我想用递归来做这个,这就是我遇到这么多困难的原因.
任何帮助将不胜感激.
谢谢!
iva*_*anm 10
这不使用递归,但更常规的方法是:
添加deriving Enum到Suit和Value的定义,然后:
makeDeck :: Deck
makeDeck = [(suit, value) | suit <- [Club..Spade], value <- [Two..Ace]]
Run Code Online (Sandbox Code Playgroud)
或者,提供所有套装和值的完全定义的列表,而不是使用Enum.
鉴于:
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)
type Deck = [Card]
makeDeck :: Deck
Run Code Online (Sandbox Code Playgroud)
有很多方法可以计算笛卡尔积——集合的积。这些示例中使用的所有函数都可以在 Hoogle 上查找:
使用 do 符号:
makeDeck = do
suit <- [Club ..]
value <- [Two ..]
return (suit, value)
Run Code Online (Sandbox Code Playgroud)
上面的无糖形式,它使用>>=:
makeDeck = [Club ..] >>= \suit ->
[Two ..] >>= \value ->
return (suit, value)
Run Code Online (Sandbox Code Playgroud)
起重:
makeDeck = liftM2 (,) [Club ..] [Two ..]
Run Code Online (Sandbox Code Playgroud)
monad 中的函数应用:
makeDeck = return (,) `ap` [Club ..] `ap` [Two ..]
Run Code Online (Sandbox Code Playgroud)
起重:
makeDeck = liftA2 (,) [Club ..] [Two ..]
Run Code Online (Sandbox Code Playgroud)
applicatives 内的函数应用:
makeDeck = pure (,) <*> [Club ..] <*> [Two ..]
Run Code Online (Sandbox Code Playgroud)
这与以下内容相同:
makeDeck = (,) <$> [Club ..] <*> [Two ..]
Run Code Online (Sandbox Code Playgroud)
请参阅@ivanm 的答案。
makeDeck = concatMap (\suit -> map ((,) suit) [Two ..]) [Club ..]
Run Code Online (Sandbox Code Playgroud)
如果您需要显式使用递归,您可以替换concatMap为它的定义,依此类推,直到到达foldr真正的递归操作发生的地方。