Consider this pseudo-pseudocode. I have quite some difficulties with the keyarg argument below,
type MapSet<K,V> = HashMap<K,HashSet<V>>;
fn contract<K,V,V1>(left: &MapSet<K,V>, right: &MapSet<V,V1>,
out: &mut MapSet<K,V1>,
keyarg: Option(__something_iterable__) {
let keys = match keyarg {
Some(keys) => {
keys
},
None => {
left.keys()
},
}
for &k in keys {
// ... do stuff ...
}
}
The function is used sometimes like this,
let x: MapSet<u32,String>;
let y: MapSet<String,u32>;
let out: MapSet<u32,u32>;
let kk: HashSet<u32>;
// ... snip ...
contract(x,y,out,kk);
And, at other times like that,
let x: MapSet<u32,String>;
let y: MapSet<String,u32>;
let out: MapSet<u32,u32>;
contract(x,y,out,None);
In other words, I am sometimes using keyarg argument to pass an Option with a reference to a HashSet containing the keys I want to iterate over and at other times I want to iterate over all the keys contained in left argument, so the keyarg becomes simply None.
But, so far I have always ended up in a problem with the match which complains that None leads to Keys object and Some branch to HashSet (type mismatch error).
My question is how to define the keyarg argument so that the branches of match are compatible with each other. That is, I want to express the fact that the variable keys is just something one can iterate over to the compiler.