I think a consequence of this view is that (x) ops are all key-based set
ops unless you explicitly make sure both sides are bags. But it's still
early enough in the morning that I've not thought this through entirely...
I understand that you want first of all 'KeyHash does Hash' and then
we have three special key handling subtypes of Hash. They differ only
in the value type. With Bit <: UInt <: Any and covariant container
typing this yields KeySet <: KeyBag <: KeyHash <: Hash. And I still
opt for Seq/List/Array entering the picture as subtypes of KeyBag
because we loose no information then.
The question is now how the mixed value case Bit and UInt from
the respective KeySet and KeyBag types are handled. I think we
should promote the Bit to an Uint and go for Bag operations. Note
that Bag operations yield set semantics when fed with set data.
The subtyping of KeyBag to KeyHash is a bit bogus because we loose
Bag semantics in so far as the Any supertype of UInt is not a
generalized multiplicity. That is KeyHash is more like KeySet but
with arbitrary items indicating presence. Actuallly the Any type
might support the needed min/max and +/- calls but I guess this is
not what a user of a KeyHash would expect when she uses it as argument
to the (x) ops.
In the end it might be more practical to make Bag an interface
subtype of Set that adds multiplicity of items that is dropped
when mixed Set Bag (x) ops are used. This is where I started before
Darren mentioned the Set <: Bag fact.
Is that enough food for thought for later in the day?