data MultiSet a = MSet [(a, Integer)] deriving Show find :: Eq a => a -> MultiSet a -> Maybe Integer find x (MSet pairs) = case filter ((== x) . fst) pairs of [(_, count)] -> Just count [] -> Nothing cardinal (MSet pairs) = foldl (+) 0 $ map snd pairs add :: Eq a => a -> MultiSet a -> MultiSet a add x set@(MSet pairs) = MSet $ (x, newcount) : otherpairs where oldcount = find x set newcount | oldcount == Nothing = 1 | True = fromJust oldcount + 1 otherpairs = filter ((/= x) . fst) pairs intersect s1@(MSet pairs1) s2@(MSet pairs2) = MSet [(key, fromJust (find key s1) `min` fromJust(find key s2)) | key <- common] where keys1 = map fst pairs1 keys2 = map fst pairs2 common = [key | key <- keys1, key `elem` keys2] example = MSet [("balaur", 1), ("dwarf", 13), ("hobbit", 1), ("wizard", 1), ("foods", 5)]