example: Rust Playground
I'm trying to make an accumulator method for iterators, similar to the Python implementation.
I can't quite figure out why it only wants to work on Iterators wrapped in Box, Arc..etc. If I wrap the calling iterator in one of those, it only works on the Box< Box < Iterator>> etc...
struct Accumulate<I>
where
I: Iterator,
{
accum: Option<I::Item>,
underlying: I,
acc_fn: Box<dyn FnMut(I::Item, I::Item) -> I::Item>,
}
impl<I> Iterator for Accumulate<I>
where
I: Iterator,
I::Item: Hash + Eq + Clone,
{
type Item = I::Item;
fn next(&mut self) -> Option<Self::Item> {
match self.underlying.next(){
Some(x) => {
let new_accum = match self.accum.clone(){
Some(accum) => (self.acc_fn)(accum, x),
None => x,
};
self.accum = Some(new_accum.clone());
Some(new_accum)
},
None => None,
}
}
}
trait Accumulator: Iterator {
fn accumulate<F: 'static>(mut self, mut f: F) -> Accumulate<Self>
where
F: FnMut(Self::Item, Self::Item) -> Self::Item,
Self::Item: Hash + Eq + Clone,
Self: Sized,
{
Accumulate {
accum: None,
underlying: self,
acc_fn: Box::new(f),
}
}
}
impl<I: Iterator> Accumulator for I {}
Error message:
error[E0599]: no method named `accumulate` found for struct `std::ops::Range<{integer}>` in the current scope
--> src/lib.rs:56:33
|
35 | fn accumulate<F: 'static>(mut self, mut f: F) -> Accumulate<Self>
| ----------
| |
| the method is available for `std::boxed::Box<std::ops::Range<{integer}>>` here
| the method is available for `std::sync::Arc<std::ops::Range<{integer}>>` here
| the method is available for `std::rc::Rc<std::ops::Range<{integer}>>` here
...
56 | let result: Vec<i32> = (1..5).accumulate(|x,y| x + y).collect();
| ^^^^^^^^^^ method not found in `std::ops::Range<{integer}>`
|
= help: items from traits can only be used if the trait is in scope
= note: the following trait is implemented but not in scope; perhaps add a `use` for it:
`use crate::Accumulator;`
Last thing, should I really be using the 'static
lifetime here? The compiler keeps recommending it but I'm not sure if I should.
Much thanks in advance