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?