Description
Update: API modified in #58062:
pub fn from_fn<T, F>(f: F) -> FromFn<F> where F: FnMut() -> Option<T> {…}
#[derive(Clone)] pub struct FromFn<F> {…}
impl<T, F> Iterator for FromFn<F> where F: FnMut() -> Option<T> {
type Item = T;
}
impl<St: fmt::Debug, F> fmt::Debug for FromFn<F> {…}
This API is being proposed in #55869:
pub fn unfold<St, T, F>(initial_state: St, f: F) -> Unfold<St, F>
where F: FnMut(&mut St) -> Option<T> {…}
#[derive(Clone)] pub struct Unfold<St, F> {…}
impl<St, T, F> Iterator for Unfold<St, F> where F: FnMut(&mut St) -> Option<T> {
type Item = T;
}
impl<St: fmt::Debug, F> fmt::Debug for Unfold<St, F> {…}
unfold
was previously in the standard library but was deprecated and then removed in Rust 1.3 for not having “gained enough traction to retain its position in the standard library”. It is now available in the itertools
crate.
My personal opinion is that we’ve been very conservative with inclusion in std in the months before and after 1.0 but we’ve slowing been relaxing the criteria, with in increasing number of small convenience functions and methods. Both unfold
and successors
feel general-purpose and fundamental enough to me to belong in the standard library.
Unresolved questions:
-
Should the state field of
Unfold
be public? -
Should
unfold
have explicit state for consistency withfold
, or should it be a more trivial bridging of closures to iterators with state kept in the closure’s environment or captures?impl<T, F> Iterator for Unfold<F> where F: FnMut() -> Option<T> { type Item = T; fn next(&mut self) -> Option<T> { (self.0)() } }
Update: moved to Moved to #58045:
pub fn successors<T, F>(first: Option<T>, succ: F) -> Successors<T, F>
where F: FnMut(&T) -> Option<T> {…}
#[derive(Clone)] pub struct Successors<T, F> {…}
impl<T, F> Iterator for Successors<T, F> where F: FnMut(&T) -> Option<T> {
type Item = T;
}
impl<T, F> FusedIterator for Successors<T, F> where F: FnMut(&T) -> Option<T> {}
impl<T: fmt::Debug, F> fmt::Debug for Successors<T, F> {…}