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