Implement FromIterator<A> for Default + Extend<A>

I think we should implement the trait FromIterator<A> for all types that conform to Default + Extend<A>. The implementation is:

impl<A, T> FromIterator<A> for T where T: Default + Extend<A> {
    fn from_iter<T: IntoIterator<Item=A>>(iter: T) -> Self {
        let mut result = <T as Default>::default();
        <T as Extend<A>>::extend(&mut result, iter);
        result
    }
}

Motivation

The signature of Iterator::unzip is:

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)
where
    FromA: Default + Extend<A>,
    FromB: Default + Extend<B>,
    Self: Sized + Iterator<Item = (A, B)>

The return type of the method unzip is a tuple of types which implement Default + Extend respectively. If we implement FromIterator<T> for all types that already implement Default + Extend<T>, we can directly use the outputs of unzip where FromIterator<T> is expected.

Adding new blanket impls is a breaking change, because someone could've added the impl manually already.

The return type of unzip is input types; the calling site decides what the return type is, and can take advantage of knowing the concrete type. FromIterator is also useless as an output type, as it doesn't provide any methods, just a constructor.

3 Likes

It should also be added that this trait combination is pretty common, this will definitely break a lot of code.

4 Likes