Richard,
Thanks for your excellent feedback! Very helpful!
> Signed multisets are unfamiliar to most of us, and I for one found the paper a little fast-paced. Can you put a bit more into the documentation?
Definitely. That's what weekends are for... :) I'll add some sections to the documentation that explain the main concepts and intuitions.
> Just for starters, I found it confusing when the documentation talks about "an element with multiplicity zero", because in the _paper_ a value that has multiplicity zero in an mzset is NOT an element of it.
I see... It seems that with multisets every value of the appropriate type is an element of the set, but some values (i.e., those with multiplicities > 0) are more of an element than others (i.e., those with multiplicity 0). In the paper this is reflected by having the "element-of" relation a ternary relation between elements, sets, and multiplicities (with a "functional dependency" from elements and sets to multiplicities). Confusingly, "not-an-element-of" notation is used as an abbreviation for "element-of with multiplicity zero".
The library labels elements with multiplicities > 0 as "members".
> For a specific example, I haven't the faintest intuition about
> what 'map' should do. Suppose we have
> {(k1)x1, (k2)x2}
> and f x1 == f x2 = y. Should the value of map f {...} be
> {(k1+k2)y} or {(k1`max`k2)y} or what?
"Should" is a tricky term here. It depends on what you consider to be the structure of a multiset. Currently, map applies its function argument copywise:
{x1_1, x1_2, ..., x1_k1, x2_1, x2_2, ..., x2_k2 }
| | | | | |
| f | f | f | f | f | f
v v v v v v
{y_1, y_2, ..., y_k1, y_k1+1, y_k1+2, ..., y_k1+k2}∑
That is, we preserve the additive structure.
But perhaps this is inconsistent: the Monoid instance for SignedMultiset operates on the extremal structure rather than the additive structure. A wrapper type Additive,
newtype Additive a = Additive (SignedMultiset a)
supplies a monoid instance that operates on the additive structure. So, perhaps, it's better to have map as it is implemented now, operate on Additive rather than SignedMultiset and have a map for SignedMultiset that uses max rather than (+).
A rationale for this would be that, this way, map would be a proper generalisation of ordinary sets. (The same rationale has been applied to union.)
Pondering over this, I realise that the difference operator also doesn't property generalise the concept for ordinary sets. However, that concept indeed seems a bit more tricky to generalise.
> Are you _sure_ that the definitions of isSubmultisetOf and
> isProperSubmultisetOf are correct? Proper sub<thing> is
> normally taken as requiring that only *one* member of the
> larger collection occur strictly fewer times in the smaller;
> here you require that for *all*.
You are right: isProperSubmultisetOf is too restrictive. I'll fix it.
Thanks,
Stefan