This is a follow up question to Use map object as function input .
I would like to pass the function compute_var_iter as an argument to another function but I'm struggling to make sense of the error messages:
This works:
use num::Float;
fn compute_var_iter<I, T>(vals: I) -> T
where
I: Iterator<Item = T>,
T: Float + std::ops::AddAssign,
{
// online variance function
let mut x = T::zero();
let mut xsquare = T::zero();
let mut len = T::zero();
for val in vals {
x += val;
xsquare += val * val;
len += T::one();
}
((xsquare / len) - (x / len) * (x / len)) / (len - T::one()) * len
}
fn main() {
let a = (1..10000001).map(|i| i as f64);
let b = (1..10000001).map(|i| i as f64);
dbg!(compute_var_iter(a.zip(b).map(|(a, b)| a * b)));
}
but when I try this:
use num::Float;
fn compute_var_iter<I, T>(vals: I) -> T
where
I: Iterator<Item = T>,
T: Float + std::ops::AddAssign,
{
// online variance function
let mut x = T::zero();
let mut xsquare = T::zero();
let mut len = T::zero();
for val in vals {
x += val;
xsquare += val * val;
len += T::one();
}
((xsquare / len) - (x / len) * (x / len)) / (len - T::one()) * len
}
fn use_fun<I, Fa, T>(aggregator: Fa, values: &[T], weights: &[T]) -> T
where
I: Iterator<Item = T>,
T: Float + std::ops::AddAssign,
Fa: Fn(I) -> T
{
aggregator(values[0..10].iter().zip(weights).map(|(x, y)| *x * *y))
}
fn main() {
let a: Vec<f64> = (1..10000001).map(|i| i as f64).collect();
let b: Vec<f64> = (1..10000001).map(|i| i as f64).collect();
dbg!(use_fun(compute_var_iter, &a, &b));
}
I get the errors:
error[E0308]: mismatched types
--> src/main.rs:43:16
|
37 | fn use_fun<I, Fa, T>(aggregator: Fa, values: &[T], weights: &[T]) -> T
| - this type parameter
...
43 | aggregator(values[0..10].iter().zip(weights).map(|(x, y)| *x * *y))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `I`, found struct `Map`
|
= note: expected type parameter `I`
found struct `Map<Zip<std::slice::Iter<'_, T>, std::slice::Iter<'_, T>>, [closure@src/main.rs:43:54: 43:70]>`
error[E0282]: type annotations needed
--> src/main.rs:54:10
|
54 | dbg!(use_fun(compute_var_iter, &a, &b));
| ^^^^^^^ cannot infer type for type parameter `I` declared on the function `use_fun`
How should the type annotation work to get this running?
use_fundoesn't use theItype → removeIfrom the declaration ofuse_funand both errors should disappear.Itype, how would we write the generic bounds?