#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 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)’
Я не знаю, как это исправить, кто-нибудь может помочь?
Комментарии:
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’ (установить руку -> вставить набор рук) пусто (колода всех рук)