In the following code, I can not figure out why the compiler is inferring the return of the process
in OuterResult
as Option<Option<T>>
instead of just Option<T>
.
Essentially, I guess I'm confused why it inferred T = Option<T>
My (naive) thought was that the filter
applied should handle the Option<T>
s that will be returned from iterating over inner_results
.
Any insight is appreciated!
trait Inner{
type Output;
fn get(&self) -> Self::Output;
}
struct InnerResult<I, F> {
iter: I,
op: F,
}
impl<I, F> Inner for InnerResult<I,F>
where
I: Iterator,
F: Fn(I::Item, I::Item) -> I::Item,
{
type Output = Option<I::Item>;
fn get(&self) -> Self::Output {
self.iter.reduce(self.op)
}
}
trait Outer{
type Output;
fn process(&self) -> Self::Output;
}
struct OuterResult<T,F>{
inner_results: Vec<Box<dyn Inner<Output = Option<T>>>>,
op: F,
}
impl<T,F> Outer for OuterResult<T, F>
where
F: Fn(T,T) -> T
{
type Output = Option<T>;
fn process(&self) -> Self::Output {
self.inner_results
.iter()
.map(|inner| inner.get())
.filter(|e| e.is_some())
.reduce(self.op)
}
}
fn main() {
let reduce_op = |x,y| x+y;
let inner1 = InnerResult {
iter: 0..5,
op: reduce_op,
};
let inner2 = InnerResult {
iter: 6..10,
op: reduce_op,
};
let outer = OuterResult {
inner_results: vec![Box::new(inner1),Box::new(inner2)],
op: reduce_op
};
let sum = outer.process();
}
Errors:
Compiling playground v0.0.1 (/playground)
error[E0277]: expected a `FnMut<(Option<T>, Option<T>)>` closure, found `F`
--> src/main.rs:43:21
|
43 | .reduce(self.op)
| ------ ^^^^^^^ expected an `FnMut<(Option<T>, Option<T>)>` closure, found `F`
| |
| required by a bound introduced by this call
|
= note: expected a closure with arguments `(T, T)`
found a closure with arguments `(Option<T>, Option<T>)`
note: required by a bound in `reduce`
--> /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/core/src/iter/traits/iterator.rs:2513:5
error[E0308]: mismatched types
--> src/main.rs:39:9
|
33 | impl<T,F> Outer for OuterResult<T, F>
| - this type parameter
...
38 | fn process(&self) -> Self::Output {
| ------------ expected `Option<T>` because of return type
39 | / self.inner_results
40 | | .iter()
41 | | .map(|inner| inner.get())
42 | | .filter(|e| e.is_some())
43 | | .reduce(self.op)
| |____________________________^ expected `Option<T>`, found `Option<Option<T>>`
|
= note: expected enum `Option<T>`
found enum `Option<Option<T>>`
Some errors have detailed explanations: E0277, E0308.
For more information about an error, try `rustc --explain E0277`.
error: could not compile `playground` (bin "playground") due to 2 previous errors