Extend Iterator with a "mean" method

rust

Solution

like it is done with `sum`

Let's review how `sum` works:

pub fn sum<S>(self) -> S
where
    S: Sum<Self::Item>, 

`sum` is implemented on any iterator, so long as the result type `S` implements `Sum` for the iterated value. The caller gets to pick the result type. `Sum` is defined as:

pub trait Sum<A = Self> {
    pub fn sum<I>(iter: I) -> Self
    where
        I: Iterator<Item = A>;
}

`Sum::sum` takes an iterator of `A` and produces a value of the type it is implemented from.

We can copy-paste the structure, changing `Sum` for `Mean` and put the straightforward implementations:

trait MeanExt: Iterator {
    fn mean<M>(self) -> M
    where
        M: Mean<Self::Item>,
        Self: Sized,
    {
        M::mean(self)
    }
}

impl<I: Iterator> MeanExt for I {}

trait Mean<A = Self> {
    fn mean<I>(iter: I) -> Self
    where
        I: Iterator<Item = A>;
}

impl Mean for f64 {
    fn mean<I>(iter: I) -> Self
    where
        I: Iterator<Item = f64>,
    {
        let mut sum = 0.0;
        let mut count: usize = 0;

        for v in iter {
            sum += v;
            count += 1;
        }

        if count > 0 {
            sum / (count as f64)
        } else {
            0.0
        }
    }
}

impl<'a> Mean<&'a f64> for f64 {
    fn mean<I>(iter: I) -> Self
    where
        I: Iterator<Item = &'a f64>,
    {
        iter.copied().mean()
    }
}

fn main() {
    let mean: f64 = [1.0, 2.0, 3.0].iter().mean();
    println!("{:?}", mean);
    let mean: f64 = std::array::IntoIter::new([-1.0, 2.0, 1.0]).mean();
    println!("{:?}", mean);
}

Problem

I'm trying to implement a `mean` method for Iterator, like it is done with `sum`. However, `sum` is `Iterator` method, so I decided to implement trait for any type that implements `Iterator`: ``` pub trait Mean<A = Self>: Sized { fn mean<I: Iterator<Item = A>>(iter: I) -> f64; } impl Mean for u64 { fn mean<I: Iterator<Item = u64>>(iter: I) -> f64 { //use zip to start enumeration from 1, not 0 iter.zip((1..)) .fold(0., |s, (e, i)| (e as f64 + s * (i - 1) as f64) / i as f64) } } impl<'a> Mean<&'a u64> for u64 { fn mean<I: Iterator<Item = &'a u64>>(iter: I) -> f64 { iter.zip((1..)) .fold(0., |s, (&e, i)| (e as f64 + s * (i - 1) as f64) / i as f64) } } trait MeanIterator: Iterator { fn mean(self) -> f64; } impl<T: Iterator> MeanIterator for T { fn mean(self) -> f64 { Mean::mean(self) } } fn main() { assert_eq!([1, 2, 3, 4, 5].iter().mean(), 3.); } ``` Playground The error: ``` error[E0282]: type annotations needed --> src/main.rs:26:9 | 26 | Mean::mean(self) | ^^^^^^^^^^ cannot infer type for `Self` ``` Is there any way to fix the code, or it is impossible in Rust?

Original source