制作一个功能,从给定的牌组构建一组最大的不同手牌

时间:2016-10-14 17:25:22

标签: haskell

我正在尝试编写一个函数,从deck构造一组最大的不同指针。我做了一个allHands函数,它提供了所有可能的5张牌,可以从给定的牌组中获取

type Deck = [Card] 

data Card = Card { rank :: Rank, suit :: Suit }
deriving (Eq, Ord)

data Rank = R2 | R3 | R4 | R5 | R6 | R7 | R8 | R9 | R10 | J | Q | K | A
deriving (Bounded, Enum, Eq, Ord)  

data Suit = S | H | D | C --spades , hearts, diamonds, clubs
deriving (Bounded, Enum, Eq, Ord, Show)

newtype Hand = Hand { unHand :: [Card] } deriving (Eq, Show)

distinctHands :: Deck -> Set Hand
distinctHands deck = foldl insert empty (allHands deck)

allHands :: Deck -> [Hand]
allHands deck = map Hand (combs 5 deck)

combs :: Int -> [a] -> [[a]]
combs 0 [] = [[]]
combs 0 xs = [[]]
combs 1 xs = map (:[]) xs 
combs n xs = [ y: ys | y:xs' <- tails xs, ys <- combs (n-1) xs']

当我在GHCi中编译我的代码时,它会出现以下错误:

Couldn't match type ‘Set Hand’ with ‘Hand’
   Expected type: Set Hand -> Set Hand -> Set Hand
   Actual type: Hand -> Set Hand -> Set Hand
   In the first argument of ‘foldl’, namely ‘insert’ 

Couldn't match type ‘Hand’ with ‘Set Hand’
   Expected type: [Set Hand]
   Actual type: [Hand]
   In the third argument of ‘foldl’, namely ‘(allHands deck)’

我不知道如何解决这个问题,任何人都可以提供帮助吗?

2 个答案:

答案 0 :(得分:2)

foldl需要一个形状为b -> a -> b的函数:

foldl :: Foldable t => (b -> a -> b) -> b -> t a -> b

insert有翻转的形状:

insert :: Ord a => a -> Set a -> Set a

您可以使用flip来解决不匹配问题:

flip :: (a -> b -> c) -> (b -> a -> c)

因此,请尝试distinctHands deck = foldl (flip insert) empty (allHands deck)。您可能也喜欢fromList函数

fromList :: Ord a => [a] -> Set a

可以让你写distinctHands = fromList . allHands

答案 1 :(得分:0)

distinctHands ::甲板->设置手 uniqueHands deck = foldl'(\ set hand-> insert hand set)空(allHands卡座)