type DeckList = [Card]
data DeckDifference = Add !Card | Remove !Card
type DeckDiff = [DeckDifference]
eqCardName, eqQuantity, eqCategory :: Card -> Card -> Bool
eqCardName (Card {name = x}) (Card {name = y}) = x == y
eqQuantity (Card {quantity = x}) (Card {quantity = y}) = x == y
eqCategory (Card {category = x}) (Card {category = y}) = x == y
diff :: DeckList -> DeckList -> DeckDiff
diff left right = go mempty (sort left) (sort right)
  where
    go :: DeckDiff -> DeckList -> DeckList -> DeckDiff
    go acc [] [] = acc
    go acc xs [] = acc ++ (Remove <$> xs)
    go acc [] ys = acc ++ (Add <$> ys)
    go acc lx@(x:xs) ly@(y:ys)
        | x < y = go (Remove x : acc) xs ly
        | x > y = go (Add x : acc) lx ys
        | otherwise = go acc xs ys