In Rust, is there any way to use trait
s and impl
s to (recursively) flatten tuples?
If it helps, something that works with N nested pairs is
Maybe for certain small definitions of "flatten", but realistically not really.
Start with the most specific implementation:
trait FlattenTuple {
fn into_flattened(self) -> (u8, u8, u8);
}
impl FlattenTuple for (u8, (u8, u8)) {
fn into_flattened(self) -> (u8, u8, u8) {
(self.0, (self.1).0, (self.1).1)
}
}
Then make it a bit more generic:
trait FlattenTuple {
type Output;
fn into_flattened(self) -> Self::Output;
}
impl FlattenTuple for (A, (B, C)) {
type Output = (A, B, C);
fn into_flattened(self) -> Self::Output {
(self.0, (self.1).0, (self.1).1)
}
}
And then repeat for every possible permutation:
impl FlattenTuple for ((A, B), C, (D, (E, F))) {
type Output = (A, B, C, D, E, F);
fn into_flattened(self) -> Self::Output {
((self.0).0, (self.0).1, self.1, (self.2).0, ((self.2).1).0, ((self.2).1).1)
}
}
These two implementations cover your two cases.
However, you'd then have to enumerate every input type you'd like, probably via code generation. There's no way I'm aware of to "inspect" the input type and then "splice" it into the output type.
You can even try to write something somewhat recursive:
impl FlattenTuple for (A, B)
where A: FlattenTuple
But this will quickly run into base-case issues: the terminal 42
doesn't implement FlattenTuple
, and if you try to impl
you will hit conflicting trait implementations.