HaloO, Darren Duncan wrote:
To start off, I should clarify that I see little value for the existence of a Bag type except for certain matters of syntactic or semantic brevity, but that those alone can still warrant its existence.
I partly agree. The Bag or MultiSet type naturally falls out as an intermediate between Set and Seq in my typing. Since I see Bag as an interface extension subtype of Set, one could e.g. derive a FuzzySet in the same way.
I think you have something backwards here. While the 3 collection types Seq,Bag,Set could be sequenced like that for some purposes of explanation, where adjacent types have commonalities that the other doesn't, I don't see that it falls to also chain .does() in the same direction all the way across. Seq and Set are *both* more specific or restricted than Bag. So it would make more sense to say 'role Set does Bag' (and 'role Seq does Bag'), not 'role Bag does Set'. For illustrative purposes, replace "Set" with "Int" and "Bag" with "Num". Everything that is a valid Set|Seq is a valid Bag, but the reverse isn't true.
All this depends on what kind of subtype you are creating. My proposal is a strict extension of the interface or internal representation. Your proposal is going the other way of restricting multiplicity to 1. It is clear that all operations of a Bag can be carried out with a Set if you take the multiplicity as 1. In the end it's a matter of choice. The coolest thing would actually be to *supertype* Bag atop of Set (see the thread 'set operations for roles').
The operators [union, intersection, difference, disjoint-union, etc] have clearly defined and predictable behaviour with a Set, since all inputs and outputs have no duplicates.
The operations of MultiSets are equally well defined. See e.g. http://en.wikipedia.org/wiki/Multiset
But I would ask whether it is desirable for those Set operators to be present in Bag|Seq, and if so, then what the desired semantics are. For example, what would these return:
The multiplicity is min for intersection and max for union.
Bag(1,2,2,2,3,3) union Bag(1,2,2,4,4); # Bag(1,1,2,2,2,2,2,3,3,4,4) or Bag(1,2,2,2,3,3,4,4) ?
So this would be Bag(1,2,2,2,3,3,4,4).
Bag(1,2,2,2,3,3) intersection Bag(1,2,2,4,4); # Bag(1,1,2,2,2,2,2) or Bag(1,2,2) ?
Bag(1,2,2) of course.
Bag(1,2,2,2,3,3) difference Bag(1,2,2,4,4); # Bag(2,3,3) or Bag(3,3) ?
Difference is taking away the intersection, so we get Bag(2,3,3). The most interesting new operation in the Bag type is the join. That yields a Bag even for Sets: Set(1,2,3) (+) Set(2,3,4) === Bag(1,2,2,3,3,4)
Bag(1,2,2,2,3,3) d_union Bag(1,2,2,4,4); # Bag(2,3,3,4,4) or Bag(3,3,4,4) ?
Disjoint union has a Bag of Pair as output. See http://en.wikipedia.org/wiki/Disjoint_union So we get Bag(1=>1, 1=>2, 1=>2, 1=>2, 1=>3, 1=>3, 2=>1, 2=>2, 2=>2, 2=>4, 2=>4). Well, or as Bag of Seq (1,1; 1,2; ... ; 2,4). Regards, TSa. --