Создание функции, которая создает максимальный набор различных рук из заданной колоды

#haskell

#хаскелл

Вопрос:

Я пытаюсь написать функцию, которая создает максимальный набор различных комбинаций из колоды. Я создал функцию 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 typeSet 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 typeHand’ with ‘Set Hand
   Expected type: [Set Hand]
   Actual type: [Hand]
   In the third argument of ‘foldl’, namely ‘(allHands deck)’
 

Я не знаю, как это исправить, кто-нибудь может помочь?

Комментарии:

1. Включите ваш импорт и определения Deck и Hand , чтобы мы могли воспроизвести вашу проблему.

2. Спасибо за ваши усилия по сокращению проблемы только до соответствующей базовой информации, это очень ценно! К сожалению, даже после вашей последней правки мне пришлось внести много изменений, чтобы создать проблему, о которой вы сообщаете. В будущем, пожалуйста, проверьте, что ваше сокращение не удалило какую-либо важную информацию.

Ответ №1:

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 .

Ответ №2:

distinctHands :: Колода -> Установить руку distinctHands deck = foldl’ (установить руку -> вставить набор рук) пусто (колода всех рук)