I am struggling with a function that is supposed to return either an f64
or an Error
. I have tried many combinations, but no success.
fn_rayon_parallel(&self) -> Result<f64, Box<dyn Error + Send + Sync>> {
let all_payoffs = (0..10000).into_par_iter().map(
|_| { //things could go very wrong here
match self.get_one_payoff() {
Ok(payoff) => {Ok(payoff)},
Err(e) => Err(e)
}
}
).collect::<Result<Vec<_>, _>>();
//this is the part I am struggling with, does not compile
//I need to return either f64 or Error
match all_payoffs {
Ok(_v) => Ok(2.34 * (1.0/10000.0) * (all_payoffs.iter().sum::<f64>())),
Err(e) => Err(From::from("There was an error in calculating Discounted Payoffs."))
}
}
Error:
error[E0277]: the trait bound `f64: std::iter::Sum<&std::vec::Vec<f64>>` is not satisfied
--> src/main.rs:81:69
|
81 | Ok(_v) => Ok(2.34 * (1.0/10000.0) * (all_payoffs.iter().sum::<f64>())),
| ^^^ the trait `std::iter::Sum<&std::vec::Vec<f64>>` is not implemented for `f64`
|
= help: the following implementations were found:
<f64 as std::iter::Sum<&'a f64>>
<f64 as std::iter::Sum>
Your main problem lies here (simplified a bit):
match all_payoffs {
Ok(_v) => Ok(1.0 * (all_payoffs.iter().sum::<f64>())),
Err(e) => { /*...*/ }
}
Note that your all_payoffs
variable is of type Result<Vec<f64>, Box<dyn Error + Send>>
. So when you do the .iter()
you think that you are getting an iterator for the values of the vector, of type &f64
, but you are instead getting an iterator for the ok-value of the Result
!!
This is handy in a lot of situations, for example you can use Iterator::flatten()
to sum all the values if Ok()
but return 0.0
if Err()
:
let x = all_payoffs.iter().flatten().sum::<f64>();
But here the compiler thinks that you are trying to sum vectors and that cannot be done, thus you get an error that says:
the trait bound
f64: std::iter::Sum<&std::vec::Vec<f64>>
is not satisfied
That basically means: you cannot sum a bunch of &Vec<f64>
and get a f64
as a result.
The solution is right there in plain sight, use that _v
:
Ok(v) => Ok(1.0 * v.iter().sum::<f64>()),
And now it works!