I'm getting confused with generic arithmetic and was wondering if someone could help explain what I'm doing wrong and why.
The following generic trait implementation works just fine as intended:
pub trait CentralMoment<Output = f64>
where
Output: Copy,
{
fn var(&self) -> Output;
fn mean(&self) -> Output;
}
impl<T: Copy + Into<f64>> CentralMoment for [T]
where
T: Copy + Into<f64>,
{
fn var(&self) -> f64 {
let mean: f64 = self.mean();
let mut ss = 0f64;
for i in 0..self.len() {
let sq_diff = (self[i].into() - mean).powf(2.);
ss += sq_diff;
}
ss / (self.len() as f64)
}
fn mean(&self) -> Output { // calculate mean }
}
But then I tried changing the implementation of fn var(&self) -> f64
so that instead of using a ranged-based loop, I use a for-each loop instead, like so:
fn var(&self) -> f64 {
let mean: f64 = self.mean();
let mut ss = 0f64;
// use for-each style loop here instead
for n in self {
let sq_diff = (*n - mean).powf(2.);
ss += sq_diff;
}
ss / (self.len() as f64)
}
But the above code now only works for Vec<{float}>
types and not Vec<{integer}>
types.
So, this works fine:
let nums = vec![5., 5., 10., 3.];
let var = nums.var();
assert_eq!(var, 6.6875)
But now I get the following compile error when I try to invoke fn var(&self) -> f64
on a vec![5, 5, 10, 3]
.
error[E0599]: the method `var` exists for struct `Vec<{integer}>`, but its trait bounds were not satisfied
--> src/lib.rs:185:24
|
185 | let var = nums.var();
| ^^^ method cannot be called on `Vec<{integer}>` due to unsatisfied trait bounds
|
= note: the following trait bounds were not satisfied:
`<{integer} as Sub<f64>>::Output = f64`
which is required by `[{integer}]: CentralMoment`
`{integer}: Sub<f64>`
which is required by `[{integer}]: CentralMoment`
I tried adding the trait bound to T: std::ops::Sub<f64, Output = f64>
, but that still didn't work. Can someone please explain where my error lies? It feels like I'm missing a key piece of information re: generics and traits that I need to go over and review.
Thank you in advance. And kindly let me know if you need any further clarification or information.