// This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. //! Iterators over immutable data. /// Create an iterator of values using a function to update an owned state /// value. /// /// The function is called with the current state as its argument, and should /// return an [`Option`][std::option::Option] of a tuple of the next value to /// yield from the iterator and the updated state. If the function returns /// [`None`][std::option::Option::None], the iterator ends. /// /// # Examples /// ``` /// # #[macro_use] extern crate im_rc as im; /// # use im::iter::unfold; /// # use im::vector::Vector; /// # use std::iter::FromIterator; /// // Create an infinite stream of numbers, starting at 0. /// let mut it = unfold(0, |i| Some((i, i + 1))); /// /// // Make a list out of its first five elements. /// let numbers = Vector::from_iter(it.take(5)); /// assert_eq!(numbers, vector![0, 1, 2, 3, 4]); /// ``` /// /// [std::option::Option]: https://doc.rust-lang.org/std/option/enum.Option.html /// [std::option::Option::None]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.None pub fn unfold(value: S, f: F) -> impl Iterator where F: Fn(S) -> Option<(A, S)>, { let mut value = Some(value); std::iter::from_fn(move || { f(value.take().unwrap()).map(|(next, state)| { value = Some(state); next }) }) }