๐Ÿฆ€ Functional Rust
๐ŸŽฌ How Rust Iterators Work Lazy evaluation, chaining, collect(), and zero-cost abstractions.
๐Ÿ“ Text version (for readers / accessibility)

โ€ข Iterators are lazy โ€” .map(), .filter(), .take() build a chain but do no work until consumed

โ€ข .collect() triggers evaluation, transforming the chain into a Vec, HashMap, or other collection

โ€ข Zero-cost abstraction: iterator chains compile to the same machine code as hand-written loops

โ€ข .iter() borrows, .into_iter() consumes, .iter_mut() borrows mutably

โ€ข Chaining replaces nested loops with a readable, composable pipeline

090: Infinite Iterators

Difficulty: Intermediate Category: Iterators Concept: Infinite sequences: `cycle()`, `repeat()`, `from_fn()` Key Insight: `take(n)` limits infinite iterators to finite consumption โ€” laziness makes infinite sequences practical
// 090: Infinite Iterators โ€” cycle, repeat, from_fn

fn main() {
    // cycle
    let v: Vec<i32> = [1, 2, 3].iter().copied().cycle().take(7).collect();
    println!("cycle: {:?}", v);

    // repeat
    let v: Vec<i32> = std::iter::repeat(42).take(4).collect();
    println!("repeat: {:?}", v);

    // from_fn
    let mut n = 0;
    let v: Vec<i32> = std::iter::from_fn(move || { let v = n; n += 1; Some(v) }).take(5).collect();
    println!("from_fn: {:?}", v);

    // repeat_with (lazy)
    let mut counter = 0;
    let v: Vec<i32> = std::iter::repeat_with(move || { counter += 1; counter }).take(5).collect();
    println!("repeat_with: {:?}", v);
}

#[cfg(test)]
mod tests {
    #[test]
    fn test_cycle() {
        let v: Vec<i32> = [1, 2, 3].iter().copied().cycle().take(7).collect();
        assert_eq!(v, vec![1, 2, 3, 1, 2, 3, 1]);
    }

    #[test]
    fn test_repeat() {
        let v: Vec<i32> = std::iter::repeat(42).take(4).collect();
        assert_eq!(v, vec![42, 42, 42, 42]);
    }

    #[test]
    fn test_from_fn() {
        let mut n = 0i32;
        let v: Vec<i32> = std::iter::from_fn(move || { let v = n; n += 1; Some(v) }).take(5).collect();
        assert_eq!(v, vec![0, 1, 2, 3, 4]);
    }

    #[test]
    fn test_repeat_with() {
        let mut c = 0;
        let v: Vec<i32> = std::iter::repeat_with(move || { c += 1; c * c }).take(4).collect();
        assert_eq!(v, vec![1, 4, 9, 16]);
    }
}
(* 090: Infinite Iterators *)

(* Approach 1: cycle *)
let cycle lst =
  let rec aux () =
    List.to_seq lst |> Seq.flat_map (fun x ->
      fun () -> Seq.Cons (x, fun () -> Seq.Nil))
  in
  let rec make original current () =
    match current () with
    | Seq.Nil -> make original (List.to_seq original) ()
    | Seq.Cons (x, rest) -> Seq.Cons (x, make original rest)
  in
  make lst (List.to_seq lst)

(* Approach 2: repeat *)
let repeat x =
  let rec aux () = Seq.Cons (x, aux) in
  aux

(* Approach 3: from_fn *)
let counter_from n =
  let c = ref n in
  fun () -> let v = !c in c := !c + 1; Seq.Cons (v, fun () -> Seq.Nil)

let take n s = List.of_seq (Seq.take n s)

(* Tests *)
let () =
  assert (take 7 (cycle [1; 2; 3]) = [1; 2; 3; 1; 2; 3; 1]);
  assert (take 4 (repeat 42) = [42; 42; 42; 42]);
  Printf.printf "โœ“ All tests passed\n"

๐Ÿ“Š Detailed Comparison

Core Insight

`take(n)` limits infinite iterators to finite consumption โ€” laziness makes infinite sequences practical

OCaml Approach

  • See example.ml for implementation

Rust Approach

  • See example.rs for implementation

Comparison Table

FeatureOCamlRust
Seeexample.mlexample.rs