I am writing a function in a trait that is a supertrait of IntoIterator to work on collections of numbers like Vec
and HashSet
. It will find the mean of the collection.
I have currently
pub trait Stats: IntoIterator + Clone {
fn sum(&self) -> Self::Item
where
Self::Item: Sum,
{
self.clone().into_iter().sum()
}
fn count(&self) -> usize {
self.clone().into_iter().count()
}
fn mean(&self) -> Self::Item
where
Self::Item: Sum + TryFrom<usize> + Div<Self::Item, Output = Self::Item>,
{
self.sum()
/ match self.count().try_into() {
Ok(v) => v,
Err(_) => panic!("Cannot convert count to item type"),
}
}
}
impl<T> Stats for T where T: IntoIterator + Clone;
It works fine for integer types, but trying to run
let v: Vec<f64> = vec![1.0, 2.0, 3.0];
assert_eq!(v.mean(), 2.0);
(yes I know that it might be 2.000000000000000000004 or whatever but this'll do for now)
the compiler complains
error[E0277]: the trait bound `f64: From<usize>` is not satisfied
--> src/lib.rs:143:22
|
143 | assert_eq!(v.mean(), 2.0);
| ^^^^ the trait `From<usize>` is not implemented for `f64`
|
= help: the following other types implement trait `From<T>`:
<f32 as From<i16>>
<f32 as From<i8>>
<f32 as From<u16>>
<f32 as From<u8>>
<f64 as From<f32>>
<f64 as From<i16>>
<f64 as From<i32>>
<f64 as From<i8>>
and 67 others
= note: required because of the requirements on the impl of `Into<f64>` for `usize`
= note: required because of the requirements on the impl of `TryFrom<usize>` for `f64`
note: required by a bound in `Stats::mean`
--> src/lib.rs:73:27
|
71 | fn mean(&self) -> Self::Item
| ---- required by a bound in this
72 | where
73 | Self::Item: Sum + TryFrom<usize> + Div<Self::Item, Output = Self::Item>,
| ^^^^^^^^^^^^^^ required by this bound in `Stats::mean`
It seems to me that f64
ought to implement TryFrom<usize>
, because afaik there aren't any values of usize that aren't representable by an f64