Consider the following example:
trait MapSlot<'a, V>
where V: 'a {
fn insert( self, val: V ) -> &'a mut V;
}
trait KeyTuple<O, I>
where O: Eq + Hash, I: Eq + Hash {
fn keys( self ) -> (O, I);
}
trait DeepEntriable<'a, O, I, V>
where O: 'a + Eq + Hash, I: 'a + Eq + Hash, V: 'a {
fn entry( &'a mut self, o: O ) -> Entry<O, HashMap<I, V>>;
}
trait DeepEntry<'a, O, I, V, DE>
where O: 'a + Eq + Hash, I: 'a + Eq + Hash, V: 'a,
KT: KeyTuple<O, I>, DE: DeepEntriable<'a, O, I, V> {
type Slot: MapSlot<'a, V>;
fn deep_entry( de: &'a mut DE, key: KT ) -> Self::Slot;
}
The example itself is not that important.
But we are constantly repeating Eq + Hash
…
What if we could reduce this?
type K = Eq + Hash;
type KA<'a> = 'a + K;
trait MapSlot<'a, V>
where V: 'a {
fn insert( self, val: V ) -> &'a mut V;
}
trait KeyTuple<O, I>
where O: K, I: K {
fn keys( self ) -> (O, I);
}
trait DeepEntriable<'a, O, I, V>
where O: KA<'a>, I: KA<'a>, V: 'a {
fn entry( &'a mut self, o: O ) -> Entry<O, HashMap<I, V>>;
}
trait DeepEntry<'a, O, I, V, DE>
where O: KA<'a>, I: KA'<a>, V: 'a,
KT: KeyTuple<O, I>, DE: DeepEntriable<'a, O, I, V> {
type Slot: MapSlot<'a, V>;
fn deep_entry( de: &'a mut DE, key: KT ) -> Self::Slot;
}
The idea is that you can use type aliases in trait bounds.
So that this would be legal:
type ValType = Add + Sub + Mul + Div;
trait CompositeOpA<V>
where V: ValType {
fn opA( a: V, b: V ) -> V
}
trait CompositeOpB<V>
where V: ValType {
fn opB( a: V, b: V ) -> V
}
Drawbacks
Perhaps there are semantic issues…?
If type
is not the appropriate keyword - maybe using
could work?