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>
impl<T> NonEmptyVec<T>
Sourcepub fn new(head: T, tail: Vec<T>) -> NonEmptyVec<T>
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}pub fn singleton(value: T) -> NonEmptyVec<T>
Sourcepub fn len(&self) -> usize
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}pub fn is_empty(&self) -> bool
Sourcepub fn iter(&self) -> impl Iterator<Item = &T>
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}Sourcepub fn tails(&self) -> NonEmptyVec<NonEmptyVec<T>>where
T: Clone,
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,
impl<T> Clone for NonEmptyVec<T>where
T: Clone,
Source§fn clone(&self) -> NonEmptyVec<T>
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)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source. Read moreSource§impl<T> Debug for NonEmptyVec<T>where
T: Debug,
impl<T> Debug for NonEmptyVec<T>where
T: Debug,
impl<T> Eq for NonEmptyVec<T>where
T: Eq,
Source§impl<T> PartialEq for NonEmptyVec<T>where
T: PartialEq,
impl<T> PartialEq for NonEmptyVec<T>where
T: PartialEq,
Source§fn eq(&self, other: &NonEmptyVec<T>) -> bool
fn eq(&self, other: &NonEmptyVec<T>) -> bool
Tests for
self and other values to be equal, and is used by ==.Source§impl<T> Semigroup for NonEmptyVec<T>
Available on crate features alloc or std only.
impl<T> Semigroup for NonEmptyVec<T>
Available on crate features
alloc or std only.fn combine(self, other: NonEmptyVec<T>) -> NonEmptyVec<T>
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> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more