Skip to main content

NonEmptyVec

Struct NonEmptyVec 

Source
pub struct NonEmptyVec<T> {
    pub head: T,
    pub tail: Vec<T>,
}
Expand description

A non-empty vector: guaranteed to have at least one element.

Fields§

§head: T§tail: Vec<T>

Implementations§

Source§

impl<T> NonEmptyVec<T>

Source

pub fn new(head: T, tail: Vec<T>) -> NonEmptyVec<T>

Examples found in repository?
examples/cellular_automaton.rs (line 104)
95fn main() {
96    println!("=== Cellular Automaton Example ===\n");
97    println!("Using Extend (Comonad) to evolve a 1D cellular automaton.\n");
98
99    // Initial state: single cell in the middle of a 21-cell grid
100    let width = 21;
101    let mid = width / 2;
102    let mut cells: Vec<u8> = vec![0; width];
103    cells[mid] = 1;
104    let initial = NonEmptyVec::new(cells[0], cells[1..].to_vec());
105
106    // Rule 90 (XOR of neighbors)
107    println!("--- Rule 90 (XOR of neighbors) ---");
108    let history = evolve(initial.clone(), rule_90, 10);
109    for (i, grid) in history.iter().enumerate() {
110        println!("  {:>2}: {}", i, display_grid(grid));
111    }
112
113    // Demonstrate Comonad::extract
114    println!("\n--- Comonad::extract (read focused cell) ---");
115    println!(
116        "  Head of initial grid: {}",
117        <NonEmptyVecF as Comonad>::extract(&initial)
118    );
119
120    // Majority rule
121    println!("\n--- Majority rule ---");
122    // Start with a more interesting pattern
123    let pattern = NonEmptyVec::new(1, vec![0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0]);
124    println!("  Initial: {}", display_grid(&pattern));
125    let history = evolve(pattern, rule_majority, 8);
126    for (i, grid) in history.iter().enumerate() {
127        println!("  {:>2}: {}", i, display_grid(grid));
128    }
129
130    // Demonstrate Extend::duplicate
131    println!("\n--- Extend::duplicate (all focused views) ---");
132    let small = NonEmptyVec::new(1, vec![2, 3]);
133    let duplicated: NonEmptyVec<NonEmptyVec<u8>> = NonEmptyVecF::duplicate(small);
134    println!("  Original: [1, 2, 3]");
135    println!("  Duplicated (each row is a focused view):");
136    for (i, view) in duplicated.iter().enumerate() {
137        let cells: Vec<String> = view.iter().map(|c| c.to_string()).collect();
138        println!("    focus {}: [{}]", i, cells.join(", "));
139    }
140}
Source

pub fn singleton(value: T) -> NonEmptyVec<T>

Source

pub fn len(&self) -> usize

Examples found in repository?
examples/cellular_automaton.rs (line 19)
16fn rule_90(grid: &NonEmptyVec<u8>) -> u8 {
17    let tails = grid.tails();
18    let current = <NonEmptyVecF as Comonad>::extract(grid);
19    let len = grid.len();
20
21    // Get left neighbor (wrapping)
22    let left = if len > 1 {
23        // The last tail gives us the rightmost element as neighbor context
24        *tails.tail.last().map(|t| &t.head).unwrap_or(&grid.head)
25    } else {
26        current
27    };
28
29    // Get right neighbor
30    let right = if grid.tail.is_empty() {
31        grid.head // wrap around
32    } else {
33        grid.tail[0]
34    };
35
36    // XOR of neighbors
37    left ^ right
38}
39
40/// Simpler rule: majority vote of (left, current, right).
41/// Cell is alive if 2+ of the three are alive.
42fn rule_majority(grid: &NonEmptyVec<u8>) -> u8 {
43    let current = <NonEmptyVecF as Comonad>::extract(grid);
44    let len = grid.len();
45
46    let left = if len > 1 {
47        let tails = grid.tails();
48        *tails.tail.last().map(|t| &t.head).unwrap_or(&grid.head)
49    } else {
50        current
51    };
52
53    let right = if grid.tail.is_empty() {
54        grid.head
55    } else {
56        grid.tail[0]
57    };
58
59    let sum = left as u16 + current as u16 + right as u16;
60    if sum >= 2 { 1 } else { 0 }
61}
Source

pub fn is_empty(&self) -> bool

Source

pub fn iter(&self) -> impl Iterator<Item = &T>

Examples found in repository?
examples/cellular_automaton.rs (line 89)
87fn display_grid(grid: &NonEmptyVec<u8>) -> String {
88    let mut s = String::new();
89    for cell in grid.iter() {
90        s.push(if *cell == 1 { '#' } else { '.' });
91    }
92    s
93}
94
95fn main() {
96    println!("=== Cellular Automaton Example ===\n");
97    println!("Using Extend (Comonad) to evolve a 1D cellular automaton.\n");
98
99    // Initial state: single cell in the middle of a 21-cell grid
100    let width = 21;
101    let mid = width / 2;
102    let mut cells: Vec<u8> = vec![0; width];
103    cells[mid] = 1;
104    let initial = NonEmptyVec::new(cells[0], cells[1..].to_vec());
105
106    // Rule 90 (XOR of neighbors)
107    println!("--- Rule 90 (XOR of neighbors) ---");
108    let history = evolve(initial.clone(), rule_90, 10);
109    for (i, grid) in history.iter().enumerate() {
110        println!("  {:>2}: {}", i, display_grid(grid));
111    }
112
113    // Demonstrate Comonad::extract
114    println!("\n--- Comonad::extract (read focused cell) ---");
115    println!(
116        "  Head of initial grid: {}",
117        <NonEmptyVecF as Comonad>::extract(&initial)
118    );
119
120    // Majority rule
121    println!("\n--- Majority rule ---");
122    // Start with a more interesting pattern
123    let pattern = NonEmptyVec::new(1, vec![0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0]);
124    println!("  Initial: {}", display_grid(&pattern));
125    let history = evolve(pattern, rule_majority, 8);
126    for (i, grid) in history.iter().enumerate() {
127        println!("  {:>2}: {}", i, display_grid(grid));
128    }
129
130    // Demonstrate Extend::duplicate
131    println!("\n--- Extend::duplicate (all focused views) ---");
132    let small = NonEmptyVec::new(1, vec![2, 3]);
133    let duplicated: NonEmptyVec<NonEmptyVec<u8>> = NonEmptyVecF::duplicate(small);
134    println!("  Original: [1, 2, 3]");
135    println!("  Duplicated (each row is a focused view):");
136    for (i, view) in duplicated.iter().enumerate() {
137        let cells: Vec<String> = view.iter().map(|c| c.to_string()).collect();
138        println!("    focus {}: [{}]", i, cells.join(", "));
139    }
140}
Source

pub fn tails(&self) -> NonEmptyVec<NonEmptyVec<T>>
where T: Clone,

Collect all suffixes as a NonEmptyVec of NonEmptyVecs.

Examples found in repository?
examples/cellular_automaton.rs (line 17)
16fn rule_90(grid: &NonEmptyVec<u8>) -> u8 {
17    let tails = grid.tails();
18    let current = <NonEmptyVecF as Comonad>::extract(grid);
19    let len = grid.len();
20
21    // Get left neighbor (wrapping)
22    let left = if len > 1 {
23        // The last tail gives us the rightmost element as neighbor context
24        *tails.tail.last().map(|t| &t.head).unwrap_or(&grid.head)
25    } else {
26        current
27    };
28
29    // Get right neighbor
30    let right = if grid.tail.is_empty() {
31        grid.head // wrap around
32    } else {
33        grid.tail[0]
34    };
35
36    // XOR of neighbors
37    left ^ right
38}
39
40/// Simpler rule: majority vote of (left, current, right).
41/// Cell is alive if 2+ of the three are alive.
42fn rule_majority(grid: &NonEmptyVec<u8>) -> u8 {
43    let current = <NonEmptyVecF as Comonad>::extract(grid);
44    let len = grid.len();
45
46    let left = if len > 1 {
47        let tails = grid.tails();
48        *tails.tail.last().map(|t| &t.head).unwrap_or(&grid.head)
49    } else {
50        current
51    };
52
53    let right = if grid.tail.is_empty() {
54        grid.head
55    } else {
56        grid.tail[0]
57    };
58
59    let sum = left as u16 + current as u16 + right as u16;
60    if sum >= 2 { 1 } else { 0 }
61}

Trait Implementations§

Source§

impl<T> Clone for NonEmptyVec<T>
where T: Clone,

Source§

fn clone(&self) -> NonEmptyVec<T>

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T> Debug for NonEmptyVec<T>
where T: Debug,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl<T> Eq for NonEmptyVec<T>
where T: Eq,

Source§

impl<T> PartialEq for NonEmptyVec<T>
where T: PartialEq,

Source§

fn eq(&self, other: &NonEmptyVec<T>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<T> Semigroup for NonEmptyVec<T>

Available on crate features alloc or std only.
Source§

fn combine(self, other: NonEmptyVec<T>) -> NonEmptyVec<T>

Source§

impl<T> StructuralPartialEq for NonEmptyVec<T>
where T: PartialEq,

Auto Trait Implementations§

§

impl<T> Freeze for NonEmptyVec<T>
where T: Freeze,

§

impl<T> RefUnwindSafe for NonEmptyVec<T>
where T: RefUnwindSafe,

§

impl<T> Send for NonEmptyVec<T>
where T: Send,

§

impl<T> Sync for NonEmptyVec<T>
where T: Sync,

§

impl<T> Unpin for NonEmptyVec<T>
where T: Unpin,

§

impl<T> UnsafeUnpin for NonEmptyVec<T>
where T: UnsafeUnpin,

§

impl<T> UnwindSafe for NonEmptyVec<T>
where T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.