Bhavye Mathur
Bhavye Mathur

Reputation: 1077

Recursive traits for flattening multidimensional vectors

Suppose I we want to flatten vectors:

[0, 50, 100] -> [0, 50, 100]
[[0], [50, 50], 100] -> [0, 50, 50, 100]
[[[0]]] -> [0]

We can define a trait such as

pub trait FlattenVec<A> {
    fn flatten(self) -> Vec<A>;
}

And apply it to nested types,

impl<A, T> FlattenVec<A> for Vec<T>
where
    T: FlattenVec<A>,
    A: AtomicType
{
    fn flatten(self) -> Vec<A> {
        self.into_iter()
            .flat_map(|nested| nested.flatten().into_iter())
            .collect()
    }
}

where AtomicType is some trait implemented for types such as i32. Then, if we write the following base case:

impl<A> FlattenVec<A> for Vec<A>
where
    A: AtomicType,
{
    fn flatten(self) -> Vec<A> {
        self
    }
}

We get the following error:

error[E0119]: conflicting implementations of trait `vector::FlattenVec<_>` for type `Vec<_>`

However, if instead we replace <A> for a concrete type such as i32 or u32, the code compiles and functions as intended.

To me, it seems that there are no conflicting implementations whenever FlattenVec<A> is mutually exclusive from AtomicType. Does anyone know why this error occurs and how we might solve it to save ourselves from having to implement the trait for each atomic type?

Upvotes: 1

Views: 36

Answers (0)

Related Questions