Thanks for sharing this viewpoint! I also like the “weighted set” intuition.
By adjusting the monoidal value type, we can reproduce several similar types (and use
newtype deriving to get instances of
Monoid, and relevant subclasses):
newtype Map k v = Map (MonoidMap k (First v)) newtype Set k = Set (MonoidMap k (Maybe ())) newtype MultiSet k = MultiSet (MonoidMap k (Sum Natural)) newtype SignedMultiSet k = SignedMultiSet (MonoidMap k (Sum Integer)) newtype MultiMap k v = MultiMap (MonoidMap k (Set v)) newtype ListMultiMap k v = ListMultiMap (MonoidMap k [v])