Skip to main content

fp_library/types/
vec.rs

1//! Functional programming trait implementations for the standard library [`Vec`] type.
2//!
3//! Extends `Vec` with [`Functor`](crate::classes::Functor), [`Monad`](crate::classes::semimonad::Semimonad), [`Foldable`](crate::classes::Foldable), [`Traversable`](crate::classes::Traversable), [`Extend`](crate::classes::Extend), [`Filterable`](crate::classes::Filterable), [`Witherable`](crate::classes::Witherable), and parallel folding instances.
4
5#[fp_macros::document_module]
6mod inner {
7	use {
8		crate::{
9			Apply,
10			brands::{
11				OptionBrand,
12				VecBrand,
13			},
14			classes::{
15				Alt,
16				Applicative,
17				ApplyFirst,
18				ApplySecond,
19				CloneableFn,
20				Compactable,
21				Extend,
22				Filterable,
23				Foldable,
24				Functor,
25				Lift,
26				MonadRec,
27				Monoid,
28				ParCompactable,
29				ParFilterable,
30				ParFoldable,
31				ParFunctor,
32				Plus,
33				Pointed,
34				Semiapplicative,
35				Semigroup,
36				Semimonad,
37				Traversable,
38				Witherable,
39				foldable_with_index::FoldableWithIndex,
40				functor_with_index::FunctorWithIndex,
41				par_foldable_with_index::ParFoldableWithIndex,
42				par_functor_with_index::ParFunctorWithIndex,
43				traversable_with_index::TraversableWithIndex,
44				with_index::WithIndex,
45			},
46			impl_kind,
47			kinds::*,
48		},
49		core::ops::ControlFlow,
50		fp_macros::*,
51	};
52
53	impl_kind! {
54		for VecBrand {
55			type Of<'a, A: 'a>: 'a = Vec<A>;
56		}
57	}
58
59	impl VecBrand {
60		/// Constructs a new vector by prepending a value to an existing vector.
61		///
62		/// This method creates a new vector with the given head element followed by the elements of the tail vector.
63		#[document_signature]
64		///
65		#[document_type_parameters("The type of the elements in the vector.")]
66		///
67		#[document_parameters(
68			"A value to prepend to the vector.",
69			"A vector to prepend the value to."
70		)]
71		///
72		#[document_returns(
73			"A new vector consisting of the `head` element prepended to the `tail` vector."
74		)]
75		#[document_examples]
76		///
77		/// ```
78		/// use fp_library::brands::VecBrand;
79		///
80		/// let head = 1;
81		/// let tail = vec![2, 3];
82		/// let new_vec = VecBrand::construct(head, tail);
83		/// assert_eq!(new_vec, vec![1, 2, 3]);
84		///
85		/// let empty_tail = vec![];
86		/// let single_element = VecBrand::construct(42, empty_tail);
87		/// assert_eq!(single_element, vec![42]);
88		/// ```
89		pub fn construct<A>(
90			head: A,
91			tail: Vec<A>,
92		) -> Vec<A>
93		where
94			A: Clone, {
95			[vec![head], tail].concat()
96		}
97
98		/// Deconstructs a slice into its head element and tail vector.
99		///
100		/// This method splits a slice into its first element and the rest of the elements as a new vector.
101		#[document_signature]
102		///
103		#[document_type_parameters("The type of the elements in the vector.")]
104		///
105		#[document_parameters("The vector slice to deconstruct.")]
106		///
107		#[document_returns(
108			"An [`Option`] containing a tuple of the head element and the remaining tail vector, or [`None`] if the slice is empty."
109		)]
110		///
111		#[document_examples]
112		///
113		/// ```
114		/// use fp_library::brands::VecBrand;
115		///
116		/// let vec = vec![1, 2, 3];
117		/// let deconstructed = VecBrand::deconstruct(&vec);
118		/// assert_eq!(deconstructed, Some((1, vec![2, 3])));
119		///
120		/// let empty: Vec<i32> = vec![];
121		/// assert_eq!(VecBrand::deconstruct(&empty), None);
122		/// ```
123		pub fn deconstruct<A>(slice: &[A]) -> Option<(A, Vec<A>)>
124		where
125			A: Clone, {
126			match slice {
127				[] => None,
128				[head, tail @ ..] => Some((head.clone(), tail.to_vec())),
129			}
130		}
131	}
132
133	impl Functor for VecBrand {
134		/// Maps a function over the vector.
135		///
136		/// This method applies a function to each element of the vector, producing a new vector with the transformed values.
137		#[document_signature]
138		///
139		#[document_type_parameters(
140			"The lifetime of the elements.",
141			"The type of the elements in the vector.",
142			"The type of the elements in the resulting vector."
143		)]
144		///
145		#[document_parameters("The function to apply to each element.", "The vector to map over.")]
146		///
147		#[document_returns("A new vector containing the results of applying the function.")]
148		///
149		#[document_examples]
150		///
151		/// ```
152		/// use fp_library::{
153		/// 	brands::*,
154		/// 	functions::*,
155		/// };
156		///
157		/// assert_eq!(map::<VecBrand, _, _>(|x: i32| x * 2, vec![1, 2, 3]), vec![2, 4, 6]);
158		/// ```
159		fn map<'a, A: 'a, B: 'a>(
160			func: impl Fn(A) -> B + 'a,
161			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
162		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
163			fa.into_iter().map(func).collect()
164		}
165	}
166
167	impl Lift for VecBrand {
168		/// Lifts a binary function into the vector context (Cartesian product).
169		///
170		/// This method applies a binary function to all pairs of elements from two vectors, producing a new vector containing the results (Cartesian product).
171		#[document_signature]
172		///
173		#[document_type_parameters(
174			"The lifetime of the elements.",
175			"The type of the elements in the first vector.",
176			"The type of the elements in the second vector.",
177			"The type of the elements in the resulting vector."
178		)]
179		///
180		#[document_parameters(
181			"The binary function to apply.",
182			"The first vector.",
183			"The second vector."
184		)]
185		///
186		#[document_returns(
187			"A new vector containing the results of applying the function to all pairs of elements."
188		)]
189		#[document_examples]
190		///
191		/// ```
192		/// use fp_library::{
193		/// 	brands::*,
194		/// 	functions::*,
195		/// };
196		///
197		/// assert_eq!(
198		/// 	lift2::<VecBrand, _, _, _>(|x, y| x + y, vec![1, 2], vec![10, 20]),
199		/// 	vec![11, 21, 12, 22]
200		/// );
201		/// ```
202		fn lift2<'a, A, B, C>(
203			func: impl Fn(A, B) -> C + 'a,
204			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
205			fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
206		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
207		where
208			A: Clone + 'a,
209			B: Clone + 'a,
210			C: 'a, {
211			fa.iter().flat_map(|a| fb.iter().map(|b| func(a.clone(), b.clone()))).collect()
212		}
213	}
214
215	impl Pointed for VecBrand {
216		/// Wraps a value in a vector.
217		///
218		/// This method creates a new vector containing the single given value.
219		#[document_signature]
220		///
221		#[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
222		///
223		#[document_parameters("The value to wrap.")]
224		///
225		#[document_returns("A vector containing the single value.")]
226		///
227		#[document_examples]
228		///
229		/// ```
230		/// use fp_library::{
231		/// 	brands::VecBrand,
232		/// 	functions::*,
233		/// };
234		///
235		/// assert_eq!(pure::<VecBrand, _>(5), vec![5]);
236		/// ```
237		fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
238			vec![a]
239		}
240	}
241
242	impl ApplyFirst for VecBrand {}
243	impl ApplySecond for VecBrand {}
244
245	impl Semiapplicative for VecBrand {
246		/// Applies wrapped functions to wrapped values (Cartesian product).
247		///
248		/// This method applies each function in the first vector to each value in the second vector, producing a new vector containing all the results.
249		#[document_signature]
250		///
251		#[document_type_parameters(
252			"The lifetime of the values.",
253			"The brand of the cloneable function wrapper.",
254			"The type of the input values.",
255			"The type of the output values."
256		)]
257		///
258		#[document_parameters(
259			"The vector containing the functions.",
260			"The vector containing the values."
261		)]
262		///
263		#[document_returns(
264			"A new vector containing the results of applying each function to each value."
265		)]
266		#[document_examples]
267		///
268		/// ```
269		/// use fp_library::{
270		/// 	brands::*,
271		/// 	classes::*,
272		/// 	functions::*,
273		/// };
274		///
275		/// let funcs = vec![
276		/// 	cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| x + 1),
277		/// 	cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2),
278		/// ];
279		/// assert_eq!(apply::<RcFnBrand, VecBrand, _, _>(funcs, vec![1, 2]), vec![2, 3, 2, 4]);
280		/// ```
281		fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
282			ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
283			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
284		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
285			ff.iter().flat_map(|f| fa.iter().map(move |a| f(a.clone()))).collect()
286		}
287	}
288
289	impl Semimonad for VecBrand {
290		/// Chains vector computations (`flat_map`).
291		///
292		/// This method applies a function that returns a vector to each element of the input vector, and then flattens the result.
293		#[document_signature]
294		///
295		#[document_type_parameters(
296			"The lifetime of the elements.",
297			"The type of the elements in the input vector.",
298			"The type of the elements in the output vector."
299		)]
300		///
301		#[document_parameters(
302			"The first vector.",
303			"The function to apply to each element, returning a vector."
304		)]
305		///
306		#[document_returns("A new vector containing the flattened results.")]
307		#[document_examples]
308		///
309		/// ```
310		/// use fp_library::{
311		/// 	brands::VecBrand,
312		/// 	functions::*,
313		/// };
314		///
315		/// assert_eq!(bind::<VecBrand, _, _>(vec![1, 2], |x| vec![x, x * 2]), vec![1, 2, 2, 4]);
316		/// ```
317		fn bind<'a, A: 'a, B: 'a>(
318			ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
319			func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
320		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
321			ma.into_iter().flat_map(func).collect()
322		}
323	}
324
325	impl Alt for VecBrand {
326		/// Concatenates two vectors.
327		///
328		/// This is the same as [`Semigroup::append`] for `Vec`, providing an
329		/// associative choice operation for the `Vec` type constructor.
330		#[document_signature]
331		///
332		#[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
333		///
334		#[document_parameters("The first vector.", "The second vector.")]
335		///
336		#[document_returns("The concatenated vector.")]
337		#[document_examples]
338		///
339		/// ```
340		/// use fp_library::{
341		/// 	brands::*,
342		/// 	classes::*,
343		/// 	functions::*,
344		/// };
345		///
346		/// let x = vec![1, 2];
347		/// let y = vec![3, 4];
348		/// assert_eq!(alt::<VecBrand, _>(x, y), vec![1, 2, 3, 4]);
349		/// ```
350		fn alt<'a, A: 'a>(
351			fa1: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
352			fa2: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
353		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
354			let mut result = fa1;
355			result.extend(fa2);
356			result
357		}
358	}
359
360	impl Plus for VecBrand {
361		/// Returns an empty vector, the identity element for [`alt`](Alt::alt).
362		#[document_signature]
363		///
364		#[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
365		///
366		#[document_returns("An empty vector.")]
367		#[document_examples]
368		///
369		/// ```
370		/// use fp_library::{
371		/// 	brands::*,
372		/// 	functions::*,
373		/// };
374		///
375		/// let x: Vec<i32> = plus_empty::<VecBrand, i32>();
376		/// assert_eq!(x, vec![]);
377		/// ```
378		fn empty<'a, A: 'a>() -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
379			Vec::new()
380		}
381	}
382
383	impl Foldable for VecBrand {
384		/// Folds the vector from the right.
385		///
386		/// This method performs a right-associative fold of the vector.
387		#[document_signature]
388		///
389		#[document_type_parameters(
390			"The lifetime of the elements.",
391			"The brand of the cloneable function to use.",
392			"The type of the elements in the vector.",
393			"The type of the accumulator."
394		)]
395		///
396		#[document_parameters("The folding function.", "The initial value.", "The vector to fold.")]
397		///
398		#[document_returns("The final accumulator value.")]
399		///
400		#[document_examples]
401		///
402		/// ```
403		/// use fp_library::{
404		/// 	brands::*,
405		/// 	functions::*,
406		/// };
407		///
408		/// assert_eq!(fold_right::<RcFnBrand, VecBrand, _, _>(|x: i32, acc| x + acc, 0, vec![1, 2, 3]), 6);
409		/// ```
410		fn fold_right<'a, FnBrand, A: 'a + Clone, B: 'a>(
411			func: impl Fn(A, B) -> B + 'a,
412			initial: B,
413			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
414		) -> B
415		where
416			FnBrand: CloneableFn + 'a, {
417			fa.into_iter().rev().fold(initial, |acc, x| func(x, acc))
418		}
419
420		/// Folds the vector from the left.
421		///
422		/// This method performs a left-associative fold of the vector.
423		#[document_signature]
424		///
425		#[document_type_parameters(
426			"The lifetime of the elements.",
427			"The brand of the cloneable function to use.",
428			"The type of the elements in the vector.",
429			"The type of the accumulator."
430		)]
431		///
432		#[document_parameters(
433			"The function to apply to the accumulator and each element.",
434			"The initial value of the accumulator.",
435			"The vector to fold."
436		)]
437		///
438		#[document_returns("The final accumulator value.")]
439		#[document_examples]
440		///
441		/// ```
442		/// use fp_library::{
443		/// 	brands::*,
444		/// 	functions::*,
445		/// };
446		///
447		/// assert_eq!(fold_left::<RcFnBrand, VecBrand, _, _>(|acc, x: i32| acc + x, 0, vec![1, 2, 3]), 6);
448		/// ```
449		fn fold_left<'a, FnBrand, A: 'a + Clone, B: 'a>(
450			func: impl Fn(B, A) -> B + 'a,
451			initial: B,
452			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
453		) -> B
454		where
455			FnBrand: CloneableFn + 'a, {
456			fa.into_iter().fold(initial, func)
457		}
458
459		/// Maps the values to a monoid and combines them.
460		///
461		/// This method maps each element of the vector to a monoid and then combines the results using the monoid's `append` operation.
462		#[document_signature]
463		///
464		#[document_type_parameters(
465			"The lifetime of the elements.",
466			"The brand of the cloneable function to use.",
467			"The type of the elements in the vector.",
468			"The type of the monoid."
469		)]
470		///
471		#[document_parameters("The mapping function.", "The vector to fold.")]
472		///
473		#[document_returns("The combined monoid value.")]
474		///
475		#[document_examples]
476		///
477		/// ```
478		/// use fp_library::{
479		/// 	brands::*,
480		/// 	functions::*,
481		/// };
482		///
483		/// assert_eq!(
484		/// 	fold_map::<RcFnBrand, VecBrand, _, _>(|x: i32| x.to_string(), vec![1, 2, 3]),
485		/// 	"123".to_string()
486		/// );
487		/// ```
488		fn fold_map<'a, FnBrand, A: 'a + Clone, M>(
489			func: impl Fn(A) -> M + 'a,
490			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
491		) -> M
492		where
493			M: Monoid + 'a,
494			FnBrand: CloneableFn + 'a, {
495			fa.into_iter().map(func).fold(M::empty(), |acc, x| M::append(acc, x))
496		}
497	}
498
499	impl Traversable for VecBrand {
500		/// Traverses the vector with an applicative function.
501		///
502		/// This method maps each element of the vector to a computation, evaluates them, and combines the results into an applicative context.
503		#[document_signature]
504		///
505		#[document_type_parameters(
506			"The lifetime of the elements.",
507			"The type of the elements in the traversable structure.",
508			"The type of the elements in the resulting traversable structure.",
509			"The applicative context."
510		)]
511		///
512		#[document_parameters(
513			"The function to apply to each element, returning a value in an applicative context.",
514			"The vector to traverse."
515		)]
516		///
517		#[document_returns("The vector wrapped in the applicative context.")]
518		#[document_examples]
519		///
520		/// ```
521		/// use fp_library::{
522		/// 	brands::{
523		/// 		OptionBrand,
524		/// 		VecBrand,
525		/// 	},
526		/// 	functions::*,
527		/// };
528		///
529		/// assert_eq!(
530		/// 	traverse::<VecBrand, _, _, OptionBrand>(|x| Some(x * 2), vec![1, 2, 3]),
531		/// 	Some(vec![2, 4, 6])
532		/// );
533		/// ```
534		fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
535			func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
536			ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
537		) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)>)
538		where
539			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
540			Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
541			let len = ta.len();
542			ta.into_iter().fold(F::pure(Vec::with_capacity(len)), |acc, x| {
543				F::lift2(
544					|mut v, b| {
545						v.push(b);
546						v
547					},
548					acc,
549					func(x),
550				)
551			})
552		}
553
554		/// Sequences a vector of applicative.
555		///
556		/// This method evaluates the computations inside the vector and accumulates the results into an applicative context.
557		#[document_signature]
558		///
559		#[document_type_parameters(
560			"The lifetime of the elements.",
561			"The type of the elements in the traversable structure.",
562			"The applicative context."
563		)]
564		///
565		#[document_parameters("The vector containing the applicative values.")]
566		///
567		#[document_returns("The vector wrapped in the applicative context.")]
568		///
569		#[document_examples]
570		///
571		/// ```
572		/// use fp_library::{
573		/// 	brands::{
574		/// 		OptionBrand,
575		/// 		VecBrand,
576		/// 	},
577		/// 	functions::*,
578		/// };
579		///
580		/// assert_eq!(sequence::<VecBrand, _, OptionBrand>(vec![Some(1), Some(2)]), Some(vec![1, 2]));
581		/// ```
582		fn sequence<'a, A: 'a + Clone, F: Applicative>(
583			ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>)>)
584		) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>)>)
585		where
586			Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
587			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
588			let len = ta.len();
589			ta.into_iter().fold(F::pure(Vec::with_capacity(len)), |acc, x| {
590				F::lift2(
591					|mut v, a| {
592						v.push(a);
593						v
594					},
595					acc,
596					x,
597				)
598			})
599		}
600	}
601
602	impl WithIndex for VecBrand {
603		type Index = usize;
604	}
605
606	impl FunctorWithIndex for VecBrand {
607		/// Maps a function over the vector, providing the index of each element.
608		#[document_signature]
609		#[document_type_parameters(
610			"The lifetime of the elements.",
611			"The type of the elements in the vector.",
612			"The type of the elements in the resulting vector."
613		)]
614		#[document_parameters(
615			"The function to apply to each element and its index.",
616			"The vector to map over."
617		)]
618		#[document_returns("A new vector containing the results of applying the function.")]
619		#[document_examples]
620		///
621		/// ```
622		/// use fp_library::{
623		/// 	brands::VecBrand,
624		/// 	functions::*,
625		/// };
626		/// let v = vec![10, 20, 30];
627		/// // Use `map_with_index` via the method on the trait, or a helper function if one existed.
628		/// // Since there's no helper function in `functions.rs` yet, we use explicit syntax or call it via trait.
629		/// use fp_library::classes::functor_with_index::FunctorWithIndex;
630		/// let mapped = <VecBrand as FunctorWithIndex>::map_with_index(|i, x| x + i as i32, v);
631		/// assert_eq!(mapped, vec![10, 21, 32]);
632		/// ```
633		fn map_with_index<'a, A: 'a, B: 'a>(
634			f: impl Fn(usize, A) -> B + 'a,
635			fa: Vec<A>,
636		) -> Vec<B> {
637			fa.into_iter().enumerate().map(|(i, a)| f(i, a)).collect()
638		}
639	}
640
641	impl FoldableWithIndex for VecBrand {
642		/// Folds the vector using a monoid, providing the index of each element.
643		#[document_signature]
644		#[document_type_parameters(
645			"The lifetime of the elements.",
646			"The type of the elements in the vector.",
647			"The monoid type."
648		)]
649		#[document_parameters(
650			"The function to apply to each element and its index.",
651			"The vector to fold."
652		)]
653		#[document_returns("The combined monoid value.")]
654		#[document_examples]
655		///
656		/// ```
657		/// use fp_library::{
658		/// 	brands::VecBrand,
659		/// 	classes::foldable_with_index::FoldableWithIndex,
660		/// 	functions::*,
661		/// };
662		/// let v = vec![10, 20, 30];
663		/// let s = <VecBrand as FoldableWithIndex>::fold_map_with_index(|i, x| format!("{}:{}", i, x), v);
664		/// assert_eq!(s, "0:101:202:30");
665		/// ```
666		fn fold_map_with_index<'a, A: 'a + Clone, R: Monoid>(
667			f: impl Fn(usize, A) -> R + 'a,
668			fa: Vec<A>,
669		) -> R {
670			fa.into_iter()
671				.enumerate()
672				.map(|(i, a)| f(i, a))
673				.fold(R::empty(), |acc, x| R::append(acc, x))
674		}
675	}
676
677	impl TraversableWithIndex for VecBrand {
678		/// Traverses the vector with an applicative function, providing the index of each element.
679		#[document_signature]
680		#[document_type_parameters(
681			"The lifetime of the elements.",
682			"The type of the elements in the vector.",
683			"The type of the elements in the resulting vector.",
684			"The applicative context."
685		)]
686		#[document_parameters(
687			"The function to apply to each element and its index, returning a value in an applicative context.",
688			"The vector to traverse."
689		)]
690		#[document_returns("The vector wrapped in the applicative context.")]
691		#[document_examples]
692		///
693		/// ```
694		/// use fp_library::{
695		/// 	brands::{
696		/// 		OptionBrand,
697		/// 		VecBrand,
698		/// 	},
699		/// 	classes::traversable_with_index::TraversableWithIndex,
700		/// 	functions::*,
701		/// };
702		/// let v = vec![10, 20, 30];
703		/// let t = <VecBrand as TraversableWithIndex>::traverse_with_index::<i32, i32, OptionBrand>(
704		/// 	|i, x| Some(x + i as i32),
705		/// 	v,
706		/// );
707		/// assert_eq!(t, Some(vec![10, 21, 32]));
708		/// ```
709		fn traverse_with_index<'a, A: 'a, B: 'a + Clone, M: Applicative>(
710			f: impl Fn(usize, A) -> M::Of<'a, B> + 'a,
711			ta: Vec<A>,
712		) -> M::Of<'a, Vec<B>> {
713			let len = ta.len();
714			ta.into_iter().enumerate().fold(M::pure(Vec::with_capacity(len)), |acc, (i, x)| {
715				M::lift2(
716					|mut v, b| {
717						v.push(b);
718						v
719					},
720					acc,
721					f(i, x),
722				)
723			})
724		}
725	}
726
727	#[document_type_parameters("The type of the elements in the vector.")]
728	impl<A: Clone> Semigroup for Vec<A> {
729		/// Appends one vector to another.
730		///
731		/// This method concatenates two vectors.
732		#[document_signature]
733		///
734		#[document_parameters("The first vector.", "The second vector.")]
735		///
736		#[document_returns("The concatenated vector.")]
737		///
738		#[document_examples]
739		///
740		/// ```
741		/// use fp_library::functions::*;
742		///
743		/// assert_eq!(append(vec![1, 2], vec![3, 4]), vec![1, 2, 3, 4]);
744		/// ```
745		fn append(
746			a: Self,
747			b: Self,
748		) -> Self {
749			[a, b].concat()
750		}
751	}
752
753	#[document_type_parameters("The type of the elements in the vector.")]
754	impl<A: Clone> Monoid for Vec<A> {
755		/// Returns an empty vector.
756		///
757		/// This method returns a new, empty vector.
758		#[document_signature]
759		///
760		#[document_returns("An empty vector.")]
761		///
762		#[document_examples]
763		///
764		/// ```
765		/// use fp_library::functions::*;
766		///
767		/// assert_eq!(empty::<Vec<i32>>(), vec![]);
768		/// ```
769		fn empty() -> Self {
770			Vec::new()
771		}
772	}
773
774	impl VecBrand {
775		/// Maps a function over the vector in parallel.
776		///
777		/// When the `rayon` feature is enabled, elements are processed across multiple threads.
778		/// Otherwise falls back to sequential mapping.
779		#[document_signature]
780		///
781		#[document_type_parameters(
782			"The lifetime of the elements.",
783			"The input element type.",
784			"The output element type."
785		)]
786		///
787		#[document_parameters(
788			"The function to apply to each element. Must be `Send + Sync`.",
789			"The vector to map over."
790		)]
791		///
792		#[document_returns("A new vector containing the mapped elements.")]
793		///
794		#[document_examples]
795		///
796		/// ```
797		/// use fp_library::brands::VecBrand;
798		///
799		/// let result = VecBrand::par_map(|x: i32| x * 2, vec![1, 2, 3]);
800		/// assert_eq!(result, vec![2, 4, 6]);
801		/// ```
802		pub fn par_map<'a, A: 'a + Send, B: 'a + Send>(
803			f: impl Fn(A) -> B + Send + Sync + 'a,
804			fa: Vec<A>,
805		) -> Vec<B> {
806			#[cfg(feature = "rayon")]
807			{
808				use rayon::prelude::*;
809				fa.into_par_iter().map(f).collect()
810			}
811			#[cfg(not(feature = "rayon"))]
812			fa.into_iter().map(f).collect()
813		}
814
815		/// Compacts a vector of options in parallel, discarding `None` values.
816		///
817		/// When the `rayon` feature is enabled, elements are processed across multiple threads.
818		/// Otherwise falls back to sequential compaction.
819		#[document_signature]
820		///
821		#[document_type_parameters("The lifetime of the elements.", "The element type.")]
822		///
823		#[document_parameters("The vector of options.")]
824		///
825		#[document_returns("A new vector containing the unwrapped `Some` values.")]
826		///
827		#[document_examples]
828		///
829		/// ```
830		/// use fp_library::brands::VecBrand;
831		///
832		/// let result = VecBrand::par_compact(vec![Some(1), None, Some(3)]);
833		/// assert_eq!(result, vec![1, 3]);
834		/// ```
835		pub fn par_compact<'a, A: 'a + Send>(fa: Vec<Option<A>>) -> Vec<A> {
836			#[cfg(feature = "rayon")]
837			{
838				use rayon::prelude::*;
839				fa.into_par_iter().flatten().collect()
840			}
841			#[cfg(not(feature = "rayon"))]
842			fa.into_iter().flatten().collect()
843		}
844
845		/// Separates a vector of results into `(errors, oks)` in parallel.
846		///
847		/// When the `rayon` feature is enabled, elements are processed across multiple threads.
848		/// Otherwise falls back to sequential separation.
849		#[document_signature]
850		///
851		#[document_type_parameters(
852			"The lifetime of the elements.",
853			"The error type.",
854			"The success type."
855		)]
856		///
857		#[document_parameters("The vector of results.")]
858		///
859		#[document_returns(
860			"A pair `(errs, oks)` where `errs` contains the `Err` values and `oks` the `Ok` values."
861		)]
862		///
863		#[document_examples]
864		///
865		/// ```
866		/// use fp_library::brands::VecBrand;
867		///
868		/// let v: Vec<Result<i32, &str>> = vec![Ok(1), Err("a"), Ok(3)];
869		/// let (errs, oks): (Vec<&str>, Vec<i32>) = VecBrand::par_separate(v);
870		/// assert_eq!(errs, vec!["a"]);
871		/// assert_eq!(oks, vec![1, 3]);
872		/// ```
873		pub fn par_separate<'a, E: 'a + Send, O: 'a + Send>(
874			fa: Vec<Result<O, E>>
875		) -> (Vec<E>, Vec<O>) {
876			#[cfg(feature = "rayon")]
877			{
878				use rayon::{
879					iter::Either,
880					prelude::*,
881				};
882				fa.into_par_iter().partition_map(|r| match r {
883					Ok(o) => Either::Right(o),
884					Err(e) => Either::Left(e),
885				})
886			}
887			#[cfg(not(feature = "rayon"))]
888			{
889				let mut errs = Vec::new();
890				let mut oks = Vec::new();
891				for result in fa {
892					match result {
893						Ok(o) => oks.push(o),
894						Err(e) => errs.push(e),
895					}
896				}
897				(errs, oks)
898			}
899		}
900
901		/// Maps and filters a vector in parallel, discarding elements where `f` returns `None`.
902		///
903		/// When the `rayon` feature is enabled, elements are processed across multiple threads.
904		/// Otherwise falls back to sequential filter-mapping.
905		#[document_signature]
906		///
907		#[document_type_parameters(
908			"The lifetime of the elements.",
909			"The input element type.",
910			"The output element type."
911		)]
912		///
913		#[document_parameters(
914			"The function to apply. Must be `Send + Sync`.",
915			"The vector to filter and map."
916		)]
917		///
918		#[document_returns("A new vector containing the `Some` results of applying `f`.")]
919		///
920		#[document_examples]
921		///
922		/// ```
923		/// use fp_library::brands::VecBrand;
924		///
925		/// let result = VecBrand::par_filter_map(
926		/// 	|x: i32| if x % 2 == 0 { Some(x * 10) } else { None },
927		/// 	vec![1, 2, 3, 4, 5],
928		/// );
929		/// assert_eq!(result, vec![20, 40]);
930		/// ```
931		pub fn par_filter_map<'a, A: 'a + Send, B: 'a + Send>(
932			f: impl Fn(A) -> Option<B> + Send + Sync + 'a,
933			fa: Vec<A>,
934		) -> Vec<B> {
935			#[cfg(feature = "rayon")]
936			{
937				use rayon::prelude::*;
938				fa.into_par_iter().filter_map(f).collect()
939			}
940			#[cfg(not(feature = "rayon"))]
941			fa.into_iter().filter_map(f).collect()
942		}
943
944		/// Filters a vector in parallel, retaining only elements satisfying `f`.
945		///
946		/// When the `rayon` feature is enabled, elements are processed across multiple threads.
947		/// Otherwise falls back to sequential filtering.
948		#[document_signature]
949		///
950		#[document_type_parameters("The lifetime of the elements.", "The element type.")]
951		///
952		#[document_parameters("The predicate. Must be `Send + Sync`.", "The vector to filter.")]
953		///
954		#[document_returns("A new vector containing only the elements satisfying `f`.")]
955		///
956		#[document_examples]
957		///
958		/// ```
959		/// use fp_library::brands::VecBrand;
960		///
961		/// let result = VecBrand::par_filter(|x: &i32| x % 2 == 0, vec![1, 2, 3, 4, 5]);
962		/// assert_eq!(result, vec![2, 4]);
963		/// ```
964		pub fn par_filter<'a, A: 'a + Send>(
965			f: impl Fn(&A) -> bool + Send + Sync + 'a,
966			fa: Vec<A>,
967		) -> Vec<A> {
968			#[cfg(feature = "rayon")]
969			{
970				use rayon::prelude::*;
971				fa.into_par_iter().filter(|a| f(a)).collect()
972			}
973			#[cfg(not(feature = "rayon"))]
974			fa.into_iter().filter(|a| f(a)).collect()
975		}
976
977		/// Maps each element to a [`Monoid`] value and combines them in parallel.
978		///
979		/// When the `rayon` feature is enabled, mapping and reduction happen across multiple threads.
980		/// Otherwise falls back to sequential fold-map.
981		#[document_signature]
982		///
983		#[document_type_parameters(
984			"The lifetime of the elements.",
985			"The element type.",
986			"The monoid type."
987		)]
988		///
989		#[document_parameters(
990			"The function mapping each element to a monoid value. Must be `Send + Sync`.",
991			"The vector to fold."
992		)]
993		///
994		#[document_returns("The combined monoid value.")]
995		///
996		#[document_examples]
997		///
998		/// ```
999		/// use fp_library::brands::VecBrand;
1000		///
1001		/// let result = VecBrand::par_fold_map(|x: i32| x.to_string(), vec![1, 2, 3]);
1002		/// assert_eq!(result, "123");
1003		/// ```
1004		pub fn par_fold_map<'a, A: 'a + Send, M: Monoid + Send + 'a>(
1005			f: impl Fn(A) -> M + Send + Sync + 'a,
1006			fa: Vec<A>,
1007		) -> M {
1008			#[cfg(feature = "rayon")]
1009			{
1010				use rayon::prelude::*;
1011				fa.into_par_iter().map(f).reduce(M::empty, |acc, m| M::append(acc, m))
1012			}
1013			#[cfg(not(feature = "rayon"))]
1014			fa.into_iter().map(f).fold(M::empty(), |acc, m| M::append(acc, m))
1015		}
1016
1017		/// Maps a function over the vector in parallel, providing each element's index.
1018		///
1019		/// When the `rayon` feature is enabled, elements are processed across multiple threads.
1020		/// Otherwise falls back to sequential indexed mapping.
1021		#[document_signature]
1022		///
1023		#[document_type_parameters(
1024			"The lifetime of the elements.",
1025			"The input element type.",
1026			"The output element type."
1027		)]
1028		///
1029		#[document_parameters(
1030			"The function to apply to each index and element. Must be `Send + Sync`.",
1031			"The vector to map over."
1032		)]
1033		///
1034		#[document_returns("A new vector containing the mapped elements.")]
1035		///
1036		#[document_examples]
1037		///
1038		/// ```
1039		/// use fp_library::brands::VecBrand;
1040		///
1041		/// let result = VecBrand::par_map_with_index(|i, x: i32| x + i as i32, vec![10, 20, 30]);
1042		/// assert_eq!(result, vec![10, 21, 32]);
1043		/// ```
1044		pub fn par_map_with_index<'a, A: 'a + Send, B: 'a + Send>(
1045			f: impl Fn(usize, A) -> B + Send + Sync + 'a,
1046			fa: Vec<A>,
1047		) -> Vec<B> {
1048			#[cfg(feature = "rayon")]
1049			{
1050				use rayon::prelude::*;
1051				fa.into_par_iter().enumerate().map(|(i, a)| f(i, a)).collect()
1052			}
1053			#[cfg(not(feature = "rayon"))]
1054			fa.into_iter().enumerate().map(|(i, a)| f(i, a)).collect()
1055		}
1056
1057		/// Maps each element and its index to a [`Monoid`] value and combines them in parallel.
1058		///
1059		/// When the `rayon` feature is enabled, mapping and reduction happen across multiple threads.
1060		/// Otherwise falls back to sequential indexed fold-map.
1061		#[document_signature]
1062		///
1063		#[document_type_parameters(
1064			"The lifetime of the elements.",
1065			"The element type.",
1066			"The monoid type."
1067		)]
1068		///
1069		#[document_parameters(
1070			"The function mapping each index and element to a monoid value. Must be `Send + Sync`.",
1071			"The vector to fold."
1072		)]
1073		///
1074		#[document_returns("The combined monoid value.")]
1075		///
1076		#[document_examples]
1077		///
1078		/// ```
1079		/// use fp_library::brands::VecBrand;
1080		///
1081		/// let result =
1082		/// 	VecBrand::par_fold_map_with_index(|i, x: i32| format!("{i}:{x}"), vec![10, 20, 30]);
1083		/// assert_eq!(result, "0:101:202:30");
1084		/// ```
1085		pub fn par_fold_map_with_index<'a, A: 'a + Send, M: Monoid + Send + 'a>(
1086			f: impl Fn(usize, A) -> M + Send + Sync + 'a,
1087			fa: Vec<A>,
1088		) -> M {
1089			#[cfg(feature = "rayon")]
1090			{
1091				use rayon::prelude::*;
1092				fa.into_par_iter()
1093					.enumerate()
1094					.map(|(i, a)| f(i, a))
1095					.reduce(M::empty, |acc, m| M::append(acc, m))
1096			}
1097			#[cfg(not(feature = "rayon"))]
1098			fa.into_iter()
1099				.enumerate()
1100				.map(|(i, a)| f(i, a))
1101				.fold(M::empty(), |acc, m| M::append(acc, m))
1102		}
1103	}
1104
1105	impl ParFunctor for VecBrand {
1106		/// Maps a function over the vector in parallel.
1107		///
1108		/// Delegates to [`VecBrand::par_map`].
1109		#[document_signature]
1110		///
1111		#[document_type_parameters(
1112			"The lifetime of the elements.",
1113			"The input element type.",
1114			"The output element type."
1115		)]
1116		///
1117		#[document_parameters(
1118			"The function to apply to each element. Must be `Send + Sync`.",
1119			"The vector to map over."
1120		)]
1121		///
1122		#[document_returns("A new vector containing the mapped elements.")]
1123		///
1124		#[document_examples]
1125		///
1126		/// ```
1127		/// use fp_library::{
1128		/// 	brands::VecBrand,
1129		/// 	classes::par_functor::ParFunctor,
1130		/// };
1131		///
1132		/// let result = VecBrand::par_map(|x: i32| x * 2, vec![1, 2, 3]);
1133		/// assert_eq!(result, vec![2, 4, 6]);
1134		/// ```
1135		fn par_map<'a, A: 'a + Send, B: 'a + Send>(
1136			f: impl Fn(A) -> B + Send + Sync + 'a,
1137			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1138		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1139			VecBrand::par_map(f, fa)
1140		}
1141	}
1142
1143	impl ParCompactable for VecBrand {
1144		/// Compacts a vector of options in parallel, discarding `None` values.
1145		///
1146		/// Delegates to [`VecBrand::par_compact`].
1147		#[document_signature]
1148		///
1149		#[document_type_parameters("The lifetime of the elements.", "The element type.")]
1150		///
1151		#[document_parameters("The vector of options.")]
1152		///
1153		#[document_returns("A new vector containing the unwrapped `Some` values.")]
1154		///
1155		#[document_examples]
1156		///
1157		/// ```
1158		/// use fp_library::{
1159		/// 	brands::VecBrand,
1160		/// 	classes::par_compactable::ParCompactable,
1161		/// };
1162		///
1163		/// let result = VecBrand::par_compact(vec![Some(1), None, Some(3)]);
1164		/// assert_eq!(result, vec![1, 3]);
1165		/// ```
1166		fn par_compact<'a, A: 'a + Send>(
1167			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
1168				'a,
1169				Apply!(<OptionBrand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1170			>)
1171		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
1172			VecBrand::par_compact(fa)
1173		}
1174
1175		/// Separates a vector of results into `(errors, oks)` in parallel.
1176		///
1177		/// Delegates to [`VecBrand::par_separate`].
1178		#[document_signature]
1179		///
1180		#[document_type_parameters(
1181			"The lifetime of the elements.",
1182			"The error type.",
1183			"The success type."
1184		)]
1185		///
1186		#[document_parameters("The vector of results.")]
1187		///
1188		#[document_returns(
1189			"A pair `(errs, oks)` where `errs` contains the `Err` values and `oks` the `Ok` values."
1190		)]
1191		///
1192		#[document_examples]
1193		///
1194		/// ```
1195		/// use fp_library::{
1196		/// 	brands::VecBrand,
1197		/// 	classes::par_compactable::ParCompactable,
1198		/// };
1199		///
1200		/// let v: Vec<Result<i32, &str>> = vec![Ok(1), Err("a"), Ok(3)];
1201		/// let (errs, oks): (Vec<&str>, Vec<i32>) = VecBrand::par_separate(v);
1202		/// assert_eq!(errs, vec!["a"]);
1203		/// assert_eq!(oks, vec![1, 3]);
1204		/// ```
1205		fn par_separate<'a, E: 'a + Send, O: 'a + Send>(
1206			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>)
1207		) -> (
1208			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
1209			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
1210		) {
1211			VecBrand::par_separate(fa)
1212		}
1213	}
1214
1215	impl ParFilterable for VecBrand {
1216		/// Maps and filters a vector in parallel, discarding elements where `f` returns `None`.
1217		///
1218		/// Single-pass implementation using rayon's `filter_map`. Delegates to
1219		/// [`VecBrand::par_filter_map`].
1220		#[document_signature]
1221		///
1222		#[document_type_parameters(
1223			"The lifetime of the elements.",
1224			"The input element type.",
1225			"The output element type."
1226		)]
1227		///
1228		#[document_parameters(
1229			"The function to apply. Must be `Send + Sync`.",
1230			"The vector to filter and map."
1231		)]
1232		///
1233		#[document_returns("A new vector containing the `Some` results of applying `f`.")]
1234		///
1235		#[document_examples]
1236		///
1237		/// ```
1238		/// use fp_library::{
1239		/// 	brands::VecBrand,
1240		/// 	classes::par_filterable::ParFilterable,
1241		/// };
1242		///
1243		/// let result = VecBrand::par_filter_map(
1244		/// 	|x: i32| if x % 2 == 0 { Some(x * 10) } else { None },
1245		/// 	vec![1, 2, 3, 4, 5],
1246		/// );
1247		/// assert_eq!(result, vec![20, 40]);
1248		/// ```
1249		fn par_filter_map<'a, A: 'a + Send, B: 'a + Send>(
1250			f: impl Fn(A) -> Option<B> + Send + Sync + 'a,
1251			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1252		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1253			VecBrand::par_filter_map(f, fa)
1254		}
1255
1256		/// Filters a vector in parallel, retaining only elements satisfying `f`.
1257		///
1258		/// Single-pass implementation using rayon's `filter`. Delegates to
1259		/// [`VecBrand::par_filter`].
1260		#[document_signature]
1261		///
1262		#[document_type_parameters("The lifetime of the elements.", "The element type.")]
1263		///
1264		#[document_parameters("The predicate. Must be `Send + Sync`.", "The vector to filter.")]
1265		///
1266		#[document_returns("A new vector containing only the elements satisfying `f`.")]
1267		///
1268		#[document_examples]
1269		///
1270		/// ```
1271		/// use fp_library::{
1272		/// 	brands::VecBrand,
1273		/// 	classes::par_filterable::ParFilterable,
1274		/// };
1275		///
1276		/// let result = VecBrand::par_filter(|x: &i32| x % 2 == 0, vec![1, 2, 3, 4, 5]);
1277		/// assert_eq!(result, vec![2, 4]);
1278		/// ```
1279		fn par_filter<'a, A: 'a + Send>(
1280			f: impl Fn(&A) -> bool + Send + Sync + 'a,
1281			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1282		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
1283			VecBrand::par_filter(f, fa)
1284		}
1285	}
1286
1287	impl ParFoldable for VecBrand {
1288		/// Maps each element to a [`Monoid`] value and combines them in parallel.
1289		///
1290		/// Delegates to [`VecBrand::par_fold_map`].
1291		#[document_signature]
1292		///
1293		#[document_type_parameters(
1294			"The lifetime of the elements.",
1295			"The element type.",
1296			"The monoid type."
1297		)]
1298		///
1299		#[document_parameters(
1300			"The function mapping each element to a monoid value. Must be `Send + Sync`.",
1301			"The vector to fold."
1302		)]
1303		///
1304		#[document_returns("The combined monoid value.")]
1305		///
1306		#[document_examples]
1307		///
1308		/// ```
1309		/// use fp_library::{
1310		/// 	brands::VecBrand,
1311		/// 	classes::par_foldable::ParFoldable,
1312		/// };
1313		///
1314		/// let result = VecBrand::par_fold_map(|x: i32| x.to_string(), vec![1, 2, 3]);
1315		/// assert_eq!(result, "123");
1316		/// ```
1317		fn par_fold_map<'a, A: 'a + Send, M: Monoid + Send + 'a>(
1318			f: impl Fn(A) -> M + Send + Sync + 'a,
1319			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1320		) -> M {
1321			VecBrand::par_fold_map(f, fa)
1322		}
1323	}
1324
1325	impl ParFunctorWithIndex for VecBrand {
1326		/// Maps a function over the vector in parallel, providing each element's index.
1327		///
1328		/// Delegates to [`VecBrand::par_map_with_index`].
1329		#[document_signature]
1330		///
1331		#[document_type_parameters(
1332			"The lifetime of the elements.",
1333			"The input element type.",
1334			"The output element type."
1335		)]
1336		///
1337		#[document_parameters(
1338			"The function to apply to each index and element. Must be `Send + Sync`.",
1339			"The vector to map over."
1340		)]
1341		///
1342		#[document_returns("A new vector containing the mapped elements.")]
1343		///
1344		#[document_examples]
1345		///
1346		/// ```
1347		/// use fp_library::{
1348		/// 	brands::VecBrand,
1349		/// 	classes::par_functor_with_index::ParFunctorWithIndex,
1350		/// };
1351		///
1352		/// let result = VecBrand::par_map_with_index(|i, x: i32| x + i as i32, vec![10, 20, 30]);
1353		/// assert_eq!(result, vec![10, 21, 32]);
1354		/// ```
1355		fn par_map_with_index<'a, A: 'a + Send, B: 'a + Send>(
1356			f: impl Fn(usize, A) -> B + Send + Sync + 'a,
1357			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1358		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
1359		where
1360			usize: Send + Sync + Copy + 'a, {
1361			VecBrand::par_map_with_index(f, fa)
1362		}
1363	}
1364
1365	impl ParFoldableWithIndex for VecBrand {
1366		/// Maps each element and its index to a [`Monoid`] value and combines them in parallel.
1367		///
1368		/// Delegates to [`VecBrand::par_fold_map_with_index`].
1369		#[document_signature]
1370		///
1371		#[document_type_parameters(
1372			"The lifetime of the elements.",
1373			"The element type.",
1374			"The monoid type."
1375		)]
1376		///
1377		#[document_parameters(
1378			"The function mapping each index and element to a monoid value. Must be `Send + Sync`.",
1379			"The vector to fold."
1380		)]
1381		///
1382		#[document_returns("The combined monoid value.")]
1383		///
1384		#[document_examples]
1385		///
1386		/// ```
1387		/// use fp_library::{
1388		/// 	brands::VecBrand,
1389		/// 	classes::par_foldable_with_index::ParFoldableWithIndex,
1390		/// };
1391		///
1392		/// let result =
1393		/// 	VecBrand::par_fold_map_with_index(|i, x: i32| format!("{i}:{x}"), vec![10, 20, 30]);
1394		/// assert_eq!(result, "0:101:202:30");
1395		/// ```
1396		fn par_fold_map_with_index<'a, A: 'a + Send, M: Monoid + Send + 'a>(
1397			f: impl Fn(usize, A) -> M + Send + Sync + 'a,
1398			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1399		) -> M
1400		where
1401			usize: Send + Sync + Copy + 'a, {
1402			VecBrand::par_fold_map_with_index(f, fa)
1403		}
1404	}
1405
1406	impl Compactable for VecBrand {
1407		/// Compacts a vector of options.
1408		///
1409		/// This method flattens a vector of options, discarding `None` values.
1410		#[document_signature]
1411		///
1412		#[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
1413		///
1414		#[document_parameters("The vector of options.")]
1415		///
1416		#[document_returns("The flattened vector.")]
1417		///
1418		#[document_examples]
1419		///
1420		/// ```
1421		/// use fp_library::{
1422		/// 	brands::VecBrand,
1423		/// 	functions::*,
1424		/// };
1425		///
1426		/// let x = vec![Some(1), None, Some(2)];
1427		/// let y = compact::<VecBrand, _>(x);
1428		/// assert_eq!(y, vec![1, 2]);
1429		/// ```
1430		fn compact<'a, A: 'a>(
1431			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
1432			'a,
1433			Apply!(<OptionBrand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1434		>)
1435		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
1436			fa.into_iter().flatten().collect()
1437		}
1438
1439		/// Separates a vector of results.
1440		///
1441		/// This method separates a vector of results into a pair of vectors.
1442		#[document_signature]
1443		///
1444		#[document_type_parameters(
1445			"The lifetime of the elements.",
1446			"The type of the error value.",
1447			"The type of the success value."
1448		)]
1449		///
1450		#[document_parameters("The vector of results.")]
1451		///
1452		#[document_returns("A pair of vectors.")]
1453		///
1454		#[document_examples]
1455		///
1456		/// ```
1457		/// use fp_library::{
1458		/// 	brands::*,
1459		/// 	functions::*,
1460		/// };
1461		///
1462		/// let x = vec![Ok(1), Err("error"), Ok(2)];
1463		/// let (errs, oks) = separate::<VecBrand, _, _>(x);
1464		/// assert_eq!(oks, vec![1, 2]);
1465		/// assert_eq!(errs, vec!["error"]);
1466		/// ```
1467		fn separate<'a, E: 'a, O: 'a>(
1468			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>)
1469		) -> (
1470			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
1471			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
1472		) {
1473			let mut oks = Vec::new();
1474			let mut errs = Vec::new();
1475			for result in fa {
1476				match result {
1477					Ok(o) => oks.push(o),
1478					Err(e) => errs.push(e),
1479				}
1480			}
1481			(errs, oks)
1482		}
1483	}
1484
1485	impl Filterable for VecBrand {
1486		/// Partitions a vector based on a function that returns a result.
1487		///
1488		/// This method partitions a vector based on a function that returns a result.
1489		#[document_signature]
1490		///
1491		#[document_type_parameters(
1492			"The lifetime of the elements.",
1493			"The type of the input value.",
1494			"The type of the error value.",
1495			"The type of the success value."
1496		)]
1497		///
1498		#[document_parameters("The function to apply.", "The vector to partition.")]
1499		///
1500		#[document_returns("A pair of vectors.")]
1501		///
1502		#[document_examples]
1503		///
1504		/// ```
1505		/// use fp_library::{
1506		/// 	brands::*,
1507		/// 	functions::*,
1508		/// };
1509		///
1510		/// let x = vec![1, 2, 3, 4];
1511		/// let (errs, oks) =
1512		/// 	partition_map::<VecBrand, _, _, _>(|a| if a % 2 == 0 { Ok(a) } else { Err(a) }, x);
1513		/// assert_eq!(oks, vec![2, 4]);
1514		/// assert_eq!(errs, vec![1, 3]);
1515		/// ```
1516		fn partition_map<'a, A: 'a, E: 'a, O: 'a>(
1517			func: impl Fn(A) -> Result<O, E> + 'a,
1518			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1519		) -> (
1520			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
1521			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
1522		) {
1523			let mut oks = Vec::new();
1524			let mut errs = Vec::new();
1525			for a in fa {
1526				match func(a) {
1527					Ok(o) => oks.push(o),
1528					Err(e) => errs.push(e),
1529				}
1530			}
1531			(errs, oks)
1532		}
1533
1534		/// Partitions a vector based on a predicate.
1535		///
1536		/// This method partitions a vector based on a predicate.
1537		#[document_signature]
1538		///
1539		#[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
1540		///
1541		#[document_parameters("The predicate.", "The vector to partition.")]
1542		///
1543		#[document_returns("A pair of vectors.")]
1544		///
1545		#[document_examples]
1546		///
1547		/// ```
1548		/// use fp_library::{
1549		/// 	brands::*,
1550		/// 	functions::*,
1551		/// };
1552		///
1553		/// let x = vec![1, 2, 3, 4];
1554		/// let (not_satisfied, satisfied) = partition::<VecBrand, _>(|a| a % 2 == 0, x);
1555		/// assert_eq!(satisfied, vec![2, 4]);
1556		/// assert_eq!(not_satisfied, vec![1, 3]);
1557		/// ```
1558		fn partition<'a, A: 'a + Clone>(
1559			func: impl Fn(A) -> bool + 'a,
1560			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1561		) -> (
1562			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1563			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1564		) {
1565			let (satisfied, not_satisfied): (Vec<A>, Vec<A>) =
1566				fa.into_iter().partition(|a| func(a.clone()));
1567			(not_satisfied, satisfied)
1568		}
1569
1570		/// Maps a function over a vector and filters out `None` results.
1571		///
1572		/// This method maps a function over a vector and filters out `None` results.
1573		#[document_signature]
1574		///
1575		#[document_type_parameters(
1576			"The lifetime of the elements.",
1577			"The type of the input value.",
1578			"The type of the result of applying the function."
1579		)]
1580		///
1581		#[document_parameters("The function to apply.", "The vector to filter and map.")]
1582		///
1583		#[document_returns("The filtered and mapped vector.")]
1584		///
1585		#[document_examples]
1586		///
1587		/// ```
1588		/// use fp_library::{
1589		/// 	brands::VecBrand,
1590		/// 	functions::*,
1591		/// };
1592		///
1593		/// let x = vec![1, 2, 3, 4];
1594		/// let y = filter_map::<VecBrand, _, _>(|a| if a % 2 == 0 { Some(a * 2) } else { None }, x);
1595		/// assert_eq!(y, vec![4, 8]);
1596		/// ```
1597		fn filter_map<'a, A: 'a, B: 'a>(
1598			func: impl Fn(A) -> Option<B> + 'a,
1599			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1600		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1601			fa.into_iter().filter_map(func).collect()
1602		}
1603
1604		/// Filters a vector based on a predicate.
1605		///
1606		/// This method filters a vector based on a predicate.
1607		#[document_signature]
1608		///
1609		#[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
1610		///
1611		#[document_parameters("The predicate.", "The vector to filter.")]
1612		///
1613		#[document_returns("The filtered vector.")]
1614		///
1615		#[document_examples]
1616		///
1617		/// ```
1618		/// use fp_library::{
1619		/// 	brands::VecBrand,
1620		/// 	functions::*,
1621		/// };
1622		///
1623		/// let x = vec![1, 2, 3, 4];
1624		/// let y = filter::<VecBrand, _>(|a| a % 2 == 0, x);
1625		/// assert_eq!(y, vec![2, 4]);
1626		/// ```
1627		fn filter<'a, A: 'a + Clone>(
1628			func: impl Fn(A) -> bool + 'a,
1629			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1630		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
1631			fa.into_iter().filter(|a| func(a.clone())).collect()
1632		}
1633	}
1634
1635	impl Witherable for VecBrand {
1636		/// Partitions a vector based on a function that returns a result in an applicative context.
1637		///
1638		/// This method partitions a vector based on a function that returns a result in an applicative context.
1639		#[document_signature]
1640		///
1641		#[document_type_parameters(
1642			"The lifetime of the elements.",
1643			"The applicative context.",
1644			"The type of the input value.",
1645			"The type of the error value.",
1646			"The type of the success value."
1647		)]
1648		///
1649		#[document_parameters("The function to apply.", "The vector to partition.")]
1650		///
1651		#[document_returns("The partitioned vector wrapped in the applicative context.")]
1652		///
1653		#[document_examples]
1654		///
1655		/// ```
1656		/// use fp_library::{
1657		/// 	brands::*,
1658		/// 	functions::*,
1659		/// };
1660		///
1661		/// let x = vec![1, 2, 3, 4];
1662		/// let y = wilt::<VecBrand, OptionBrand, _, _, _>(
1663		/// 	|a| Some(if a % 2 == 0 { Ok(a) } else { Err(a) }),
1664		/// 	x,
1665		/// );
1666		/// assert_eq!(y, Some((vec![1, 3], vec![2, 4])));
1667		/// ```
1668		fn wilt<'a, M: Applicative, A: 'a + Clone, E: 'a + Clone, O: 'a + Clone>(
1669			func: impl Fn(A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>)
1670			+ 'a,
1671			ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1672		) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
1673		'a,
1674		(
1675			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
1676			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
1677		),
1678	>)
1679		where
1680			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>): Clone,
1681			Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>): Clone, {
1682			ta.into_iter().fold(M::pure((Vec::new(), Vec::new())), |acc, x| {
1683				M::lift2(
1684					|mut pair, res| {
1685						match res {
1686							Ok(o) => pair.1.push(o),
1687							Err(e) => pair.0.push(e),
1688						}
1689						pair
1690					},
1691					acc,
1692					func(x),
1693				)
1694			})
1695		}
1696
1697		/// Maps a function over a vector and filters out `None` results in an applicative context.
1698		///
1699		/// This method maps a function over a vector and filters out `None` results in an applicative context.
1700		#[document_signature]
1701		///
1702		#[document_type_parameters(
1703			"The lifetime of the values.",
1704			"The applicative context.",
1705			"The type of the elements in the input structure.",
1706			"The type of the result of applying the function."
1707		)]
1708		///
1709		#[document_parameters(
1710			"The function to apply to each element, returning an `Option` in an applicative context.",
1711			"The vector to filter and map."
1712		)]
1713		///
1714		#[document_returns("The filtered and mapped vector wrapped in the applicative context.")]
1715		#[document_examples]
1716		///
1717		/// ```
1718		/// use fp_library::{
1719		/// 	brands::{
1720		/// 		OptionBrand,
1721		/// 		VecBrand,
1722		/// 	},
1723		/// 	functions::*,
1724		/// };
1725		///
1726		/// let x = vec![1, 2, 3, 4];
1727		/// let y = wither::<VecBrand, OptionBrand, _, _>(
1728		/// 	|a| Some(if a % 2 == 0 { Some(a * 2) } else { None }),
1729		/// 	x,
1730		/// );
1731		/// assert_eq!(y, Some(vec![4, 8]));
1732		/// ```
1733		fn wither<'a, M: Applicative, A: 'a + Clone, B: 'a + Clone>(
1734			func: impl Fn(A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>) + 'a,
1735			ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1736		) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
1737		'a,
1738		Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
1739	>)
1740		where
1741			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>): Clone,
1742			Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>): Clone, {
1743			ta.into_iter().fold(M::pure(Vec::new()), |acc, x| {
1744				M::lift2(
1745					|mut v, opt_b| {
1746						if let Some(b) = opt_b {
1747							v.push(b);
1748						}
1749						v
1750					},
1751					acc,
1752					func(x),
1753				)
1754			})
1755		}
1756	}
1757
1758	/// Cooperative extension for [`Vec`], ported from PureScript's `Extend Array` instance.
1759	///
1760	/// `extend(f, vec)` produces a new vector where each element at index `i` is
1761	/// `f` applied to the suffix `vec[i..]`. This is the dual of [`Semimonad::bind`]:
1762	/// where `bind` feeds each element into a function that produces a new context,
1763	/// `extend` feeds each suffix (context) into a function that produces a single value.
1764	///
1765	/// Requires `A: Clone` because suffixes are materialized as owned vectors.
1766	impl Extend for VecBrand {
1767		/// Extends a local context-dependent computation to a global computation over
1768		/// [`Vec`].
1769		///
1770		/// Applies `f` to every suffix of the input vector. For a vector
1771		/// `[a, b, c]`, the result is `[f([a, b, c]), f([b, c]), f([c])]`.
1772		#[document_signature]
1773		///
1774		#[document_type_parameters(
1775			"The lifetime of the values.",
1776			"The type of the elements in the vector.",
1777			"The result type of the extension function."
1778		)]
1779		///
1780		#[document_parameters(
1781			"The function that consumes a suffix vector and produces a value.",
1782			"The vector to extend over."
1783		)]
1784		///
1785		#[document_returns(
1786			"A new vector containing the results of applying the function to each suffix."
1787		)]
1788		///
1789		#[document_examples]
1790		///
1791		/// ```
1792		/// use fp_library::{
1793		/// 	brands::*,
1794		/// 	functions::*,
1795		/// };
1796		///
1797		/// let result = extend::<VecBrand, _, _>(|v: Vec<i32>| v.iter().sum::<i32>(), vec![1, 2, 3]);
1798		/// assert_eq!(result, vec![6, 5, 3]);
1799		/// ```
1800		fn extend<'a, A: 'a + Clone, B: 'a>(
1801			f: impl Fn(Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>)) -> B + 'a,
1802			wa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1803		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1804			(0 .. wa.len()).map(|i| f(wa.get(i ..).unwrap_or_default().to_vec())).collect()
1805		}
1806	}
1807
1808	impl MonadRec for VecBrand {
1809		/// Performs tail-recursive monadic computation over [`Vec`].
1810		///
1811		/// Since `Vec` represents nondeterminism, this performs a breadth-first
1812		/// expansion: each iteration maps all current `Loop` states through the step
1813		/// function, collecting `Done` results as they appear. The computation
1814		/// terminates when no `Loop` values remain.
1815		#[document_signature]
1816		///
1817		#[document_type_parameters(
1818			"The lifetime of the computation.",
1819			"The type of the initial value and loop state.",
1820			"The type of the result."
1821		)]
1822		///
1823		#[document_parameters("The step function.", "The initial value.")]
1824		///
1825		#[document_returns("A vector of all completed results.")]
1826		///
1827		#[document_examples]
1828		///
1829		/// ```
1830		/// use {
1831		/// 	core::ops::ControlFlow,
1832		/// 	fp_library::{
1833		/// 		brands::*,
1834		/// 		functions::*,
1835		/// 		types::*,
1836		/// 	},
1837		/// };
1838		///
1839		/// // Branch into two paths, each running until done
1840		/// let result = tail_rec_m::<VecBrand, _, _>(
1841		/// 	|n| {
1842		/// 		if n < 3 {
1843		/// 			vec![ControlFlow::Continue(n + 1), ControlFlow::Break(n * 10)]
1844		/// 		} else {
1845		/// 			vec![ControlFlow::Break(n * 10)]
1846		/// 		}
1847		/// 	},
1848		/// 	0,
1849		/// );
1850		/// // Starting from 0: branches at 0,1,2; done at 3
1851		/// assert_eq!(result, vec![0, 10, 20, 30]);
1852		/// ```
1853		fn tail_rec_m<'a, A: 'a, B: 'a>(
1854			func: impl Fn(
1855				A,
1856			)
1857				-> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, ControlFlow<B, A>>)
1858			+ 'a,
1859			initial: A,
1860		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1861			let mut done: Vec<B> = Vec::new();
1862			let mut pending: Vec<A> = vec![initial];
1863			while !pending.is_empty() {
1864				let mut next_pending: Vec<A> = Vec::new();
1865				for a in pending {
1866					for step in func(a) {
1867						match step {
1868							ControlFlow::Continue(next) => next_pending.push(next),
1869							ControlFlow::Break(b) => done.push(b),
1870						}
1871					}
1872				}
1873				pending = next_pending;
1874			}
1875			done
1876		}
1877	}
1878}
1879
1880#[cfg(test)]
1881mod tests {
1882
1883	use {
1884		crate::{
1885			brands::*,
1886			classes::CloneableFn,
1887			functions::*,
1888		},
1889		quickcheck_macros::quickcheck,
1890	};
1891
1892	// Functor Laws
1893
1894	/// Tests the identity law for Functor.
1895	#[quickcheck]
1896	fn functor_identity(x: Vec<i32>) -> bool {
1897		map::<VecBrand, _, _>(identity, x.clone()) == x
1898	}
1899
1900	/// Tests the composition law for Functor.
1901	#[quickcheck]
1902	fn functor_composition(x: Vec<i32>) -> bool {
1903		let f = |x: i32| x.wrapping_add(1);
1904		let g = |x: i32| x.wrapping_mul(2);
1905		map::<VecBrand, _, _>(compose(f, g), x.clone())
1906			== map::<VecBrand, _, _>(f, map::<VecBrand, _, _>(g, x))
1907	}
1908
1909	// Applicative Laws
1910
1911	/// Tests the identity law for Applicative.
1912	#[quickcheck]
1913	fn applicative_identity(v: Vec<i32>) -> bool {
1914		apply::<RcFnBrand, VecBrand, _, _>(
1915			pure::<VecBrand, _>(<RcFnBrand as CloneableFn>::new(identity)),
1916			v.clone(),
1917		) == v
1918	}
1919
1920	/// Tests the homomorphism law for Applicative.
1921	#[quickcheck]
1922	fn applicative_homomorphism(x: i32) -> bool {
1923		let f = |x: i32| x.wrapping_mul(2);
1924		apply::<RcFnBrand, VecBrand, _, _>(
1925			pure::<VecBrand, _>(<RcFnBrand as CloneableFn>::new(f)),
1926			pure::<VecBrand, _>(x),
1927		) == pure::<VecBrand, _>(f(x))
1928	}
1929
1930	/// Tests the composition law for Applicative.
1931	#[quickcheck]
1932	fn applicative_composition(
1933		w: Vec<i32>,
1934		u_seeds: Vec<i32>,
1935		v_seeds: Vec<i32>,
1936	) -> bool {
1937		let u_fns: Vec<_> = u_seeds
1938			.iter()
1939			.map(|&i| <RcFnBrand as CloneableFn>::new(move |x: i32| x.wrapping_add(i)))
1940			.collect();
1941		let v_fns: Vec<_> = v_seeds
1942			.iter()
1943			.map(|&i| <RcFnBrand as CloneableFn>::new(move |x: i32| x.wrapping_mul(i)))
1944			.collect();
1945
1946		// RHS: u <*> (v <*> w)
1947		let vw = apply::<RcFnBrand, VecBrand, _, _>(v_fns.clone(), w.clone());
1948		let rhs = apply::<RcFnBrand, VecBrand, _, _>(u_fns.clone(), vw);
1949
1950		// LHS: pure(compose) <*> u <*> v <*> w
1951		// equivalent to (u . v) <*> w
1952		// We construct (u . v) manually as the cartesian product of compositions
1953		let uv_fns: Vec<_> = u_fns
1954			.iter()
1955			.flat_map(|uf| {
1956				v_fns.iter().map(move |vf| {
1957					let uf = uf.clone();
1958					let vf = vf.clone();
1959					<RcFnBrand as CloneableFn>::new(move |x| uf(vf(x)))
1960				})
1961			})
1962			.collect();
1963
1964		let lhs = apply::<RcFnBrand, VecBrand, _, _>(uv_fns, w);
1965
1966		lhs == rhs
1967	}
1968
1969	/// Tests the interchange law for Applicative.
1970	#[quickcheck]
1971	fn applicative_interchange(y: i32) -> bool {
1972		// u <*> pure y = pure ($ y) <*> u
1973		let f = |x: i32| x.wrapping_mul(2);
1974		let u = vec![<RcFnBrand as CloneableFn>::new(f)];
1975
1976		let lhs = apply::<RcFnBrand, VecBrand, _, _>(u.clone(), pure::<VecBrand, _>(y));
1977
1978		let rhs_fn =
1979			<RcFnBrand as CloneableFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
1980		let rhs = apply::<RcFnBrand, VecBrand, _, _>(pure::<VecBrand, _>(rhs_fn), u);
1981
1982		lhs == rhs
1983	}
1984
1985	// Semigroup Laws
1986
1987	/// Tests the associativity law for Semigroup.
1988	#[quickcheck]
1989	fn semigroup_associativity(
1990		a: Vec<i32>,
1991		b: Vec<i32>,
1992		c: Vec<i32>,
1993	) -> bool {
1994		append(a.clone(), append(b.clone(), c.clone())) == append(append(a, b), c)
1995	}
1996
1997	// Monoid Laws
1998
1999	/// Tests the left identity law for Monoid.
2000	#[quickcheck]
2001	fn monoid_left_identity(a: Vec<i32>) -> bool {
2002		append(empty::<Vec<i32>>(), a.clone()) == a
2003	}
2004
2005	/// Tests the right identity law for Monoid.
2006	#[quickcheck]
2007	fn monoid_right_identity(a: Vec<i32>) -> bool {
2008		append(a.clone(), empty::<Vec<i32>>()) == a
2009	}
2010
2011	// Monad Laws
2012
2013	/// Tests the left identity law for Monad.
2014	#[quickcheck]
2015	fn monad_left_identity(a: i32) -> bool {
2016		let f = |x: i32| vec![x.wrapping_mul(2)];
2017		bind::<VecBrand, _, _>(pure::<VecBrand, _>(a), f) == f(a)
2018	}
2019
2020	/// Tests the right identity law for Monad.
2021	#[quickcheck]
2022	fn monad_right_identity(m: Vec<i32>) -> bool {
2023		bind::<VecBrand, _, _>(m.clone(), pure::<VecBrand, _>) == m
2024	}
2025
2026	/// Tests the associativity law for Monad.
2027	#[quickcheck]
2028	fn monad_associativity(m: Vec<i32>) -> bool {
2029		let f = |x: i32| vec![x.wrapping_mul(2)];
2030		let g = |x: i32| vec![x.wrapping_add(1)];
2031		bind::<VecBrand, _, _>(bind::<VecBrand, _, _>(m.clone(), f), g)
2032			== bind::<VecBrand, _, _>(m, |x| bind::<VecBrand, _, _>(f(x), g))
2033	}
2034
2035	// Edge Cases
2036
2037	/// Tests `map` on an empty vector.
2038	#[test]
2039	fn map_empty() {
2040		assert_eq!(map::<VecBrand, _, _>(|x: i32| x + 1, vec![] as Vec<i32>), vec![] as Vec<i32>);
2041	}
2042
2043	/// Tests `bind` on an empty vector.
2044	#[test]
2045	fn bind_empty() {
2046		assert_eq!(
2047			bind::<VecBrand, _, _>(vec![] as Vec<i32>, |x: i32| vec![x + 1]),
2048			vec![] as Vec<i32>
2049		);
2050	}
2051
2052	/// Tests `bind` returning an empty vector.
2053	#[test]
2054	fn bind_returning_empty() {
2055		assert_eq!(
2056			bind::<VecBrand, _, _>(vec![1, 2, 3], |_| vec![] as Vec<i32>),
2057			vec![] as Vec<i32>
2058		);
2059	}
2060
2061	/// Tests `fold_right` on an empty vector.
2062	#[test]
2063	fn fold_right_empty() {
2064		assert_eq!(
2065			crate::classes::foldable::fold_right::<RcFnBrand, VecBrand, _, _>(
2066				|x: i32, acc| x + acc,
2067				0,
2068				vec![]
2069			),
2070			0
2071		);
2072	}
2073
2074	/// Tests `fold_left` on an empty vector.
2075	#[test]
2076	fn fold_left_empty() {
2077		assert_eq!(
2078			crate::classes::foldable::fold_left::<RcFnBrand, VecBrand, _, _>(
2079				|acc, x: i32| acc + x,
2080				0,
2081				vec![]
2082			),
2083			0
2084		);
2085	}
2086
2087	/// Tests `traverse` on an empty vector.
2088	#[test]
2089	fn traverse_empty() {
2090		use crate::brands::OptionBrand;
2091		assert_eq!(
2092			crate::classes::traversable::traverse::<VecBrand, _, _, OptionBrand>(
2093				|x: i32| Some(x + 1),
2094				vec![]
2095			),
2096			Some(vec![])
2097		);
2098	}
2099
2100	/// Tests `traverse` returning an empty vector.
2101	#[test]
2102	fn traverse_returning_empty() {
2103		use crate::brands::OptionBrand;
2104		assert_eq!(
2105			crate::classes::traversable::traverse::<VecBrand, _, _, OptionBrand>(
2106				|_: i32| None::<i32>,
2107				vec![1, 2, 3]
2108			),
2109			None
2110		);
2111	}
2112
2113	/// Tests `construct` with an empty tail.
2114	#[test]
2115	fn construct_empty_tail() {
2116		assert_eq!(VecBrand::construct(1, vec![]), vec![1]);
2117	}
2118
2119	/// Tests `deconstruct` on an empty slice.
2120	#[test]
2121	fn deconstruct_empty() {
2122		assert_eq!(VecBrand::deconstruct::<i32>(&[]), None);
2123	}
2124
2125	// Parallel Trait Tests
2126
2127	/// Tests `par_map` on a vector.
2128	#[test]
2129	fn par_map_basic() {
2130		let v = vec![1, 2, 3];
2131		let result: Vec<i32> = par_map::<VecBrand, _, _>(|x: i32| x * 2, v);
2132		assert_eq!(result, vec![2, 4, 6]);
2133	}
2134
2135	/// Tests `par_filter` on a vector.
2136	#[test]
2137	fn par_filter_basic() {
2138		let v = vec![1, 2, 3, 4, 5];
2139		let result: Vec<i32> = par_filter::<VecBrand, _>(|x: &i32| x % 2 == 0, v);
2140		assert_eq!(result, vec![2, 4]);
2141	}
2142
2143	/// Tests `par_filter_map` on a vector.
2144	#[test]
2145	fn par_filter_map_basic() {
2146		let v = vec![1, 2, 3, 4, 5];
2147		let result: Vec<i32> = par_filter_map::<VecBrand, _, _>(
2148			|x: i32| if x % 2 == 0 { Some(x * 10) } else { None },
2149			v,
2150		);
2151		assert_eq!(result, vec![20, 40]);
2152	}
2153
2154	/// Tests `par_compact` on a vector of options.
2155	#[test]
2156	fn par_compact_basic() {
2157		let v = vec![Some(1), None, Some(3), None, Some(5)];
2158		let result: Vec<i32> = par_compact::<VecBrand, _>(v);
2159		assert_eq!(result, vec![1, 3, 5]);
2160	}
2161
2162	/// Tests `par_separate` on a vector of results.
2163	#[test]
2164	fn par_separate_basic() {
2165		let v: Vec<Result<i32, &str>> = vec![Ok(1), Err("a"), Ok(3), Err("b")];
2166		let (errs, oks): (Vec<&str>, Vec<i32>) = par_separate::<VecBrand, _, _>(v);
2167		assert_eq!(errs, vec!["a", "b"]);
2168		assert_eq!(oks, vec![1, 3]);
2169	}
2170
2171	/// Tests `par_map_with_index` on a vector.
2172	#[test]
2173	fn par_map_with_index_basic() {
2174		let v = vec![10, 20, 30];
2175		let result: Vec<i32> = par_map_with_index::<VecBrand, _, _>(|i, x: i32| x + i as i32, v);
2176		assert_eq!(result, vec![10, 21, 32]);
2177	}
2178
2179	/// Tests `par_fold_map` on an empty vector.
2180	#[test]
2181	fn par_fold_map_empty() {
2182		let v: Vec<i32> = vec![];
2183		assert_eq!(par_fold_map::<VecBrand, _, _>(|x: i32| x.to_string(), v), "".to_string());
2184	}
2185
2186	/// Tests `par_fold_map` on multiple elements.
2187	#[test]
2188	fn par_fold_map_multiple() {
2189		let v = vec![1, 2, 3];
2190		assert_eq!(par_fold_map::<VecBrand, _, _>(|x: i32| x.to_string(), v), "123".to_string());
2191	}
2192
2193	/// Tests `par_fold_map_with_index` on a vector.
2194	#[test]
2195	fn par_fold_map_with_index_basic() {
2196		let v = vec![10, 20, 30];
2197		let result: String =
2198			par_fold_map_with_index::<VecBrand, _, _>(|i, x: i32| format!("{i}:{x}"), v);
2199		assert_eq!(result, "0:101:202:30");
2200	}
2201
2202	// Filterable Laws
2203
2204	/// Tests `filterMap identity ≡ compact`.
2205	#[quickcheck]
2206	fn filterable_filter_map_identity(x: Vec<Option<i32>>) -> bool {
2207		filter_map::<VecBrand, _, _>(identity, x.clone()) == compact::<VecBrand, _>(x)
2208	}
2209
2210	/// Tests `filterMap Just ≡ identity`.
2211	#[quickcheck]
2212	fn filterable_filter_map_just(x: Vec<i32>) -> bool {
2213		filter_map::<VecBrand, _, _>(Some, x.clone()) == x
2214	}
2215
2216	/// Tests `filterMap (l <=< r) ≡ filterMap l <<< filterMap r`.
2217	#[quickcheck]
2218	fn filterable_filter_map_composition(x: Vec<i32>) -> bool {
2219		let r = |i: i32| if i % 2 == 0 { Some(i) } else { None };
2220		let l = |i: i32| if i > 5 { Some(i) } else { None };
2221		let composed = |i| bind::<OptionBrand, _, _>(r(i), l);
2222
2223		filter_map::<VecBrand, _, _>(composed, x.clone())
2224			== filter_map::<VecBrand, _, _>(l, filter_map::<VecBrand, _, _>(r, x))
2225	}
2226
2227	/// Tests `filter ≡ filterMap <<< maybeBool`.
2228	#[quickcheck]
2229	fn filterable_filter_consistency(x: Vec<i32>) -> bool {
2230		let p = |i: i32| i % 2 == 0;
2231		let maybe_bool = |i| if p(i) { Some(i) } else { None };
2232
2233		filter::<VecBrand, _>(p, x.clone()) == filter_map::<VecBrand, _, _>(maybe_bool, x)
2234	}
2235
2236	/// Tests `partitionMap identity ≡ separate`.
2237	#[quickcheck]
2238	fn filterable_partition_map_identity(x: Vec<Result<i32, i32>>) -> bool {
2239		partition_map::<VecBrand, _, _, _>(identity, x.clone()) == separate::<VecBrand, _, _>(x)
2240	}
2241
2242	/// Tests `partitionMap Right ≡ identity` (on the right side).
2243	#[quickcheck]
2244	fn filterable_partition_map_right_identity(x: Vec<i32>) -> bool {
2245		let (_, oks) = partition_map::<VecBrand, _, _, _>(Ok::<_, i32>, x.clone());
2246		oks == x
2247	}
2248
2249	/// Tests `partitionMap Left ≡ identity` (on the left side).
2250	#[quickcheck]
2251	fn filterable_partition_map_left_identity(x: Vec<i32>) -> bool {
2252		let (errs, _) = partition_map::<VecBrand, _, _, _>(Err::<i32, _>, x.clone());
2253		errs == x
2254	}
2255
2256	/// Tests `f <<< partition ≡ partitionMap <<< eitherBool`.
2257	#[quickcheck]
2258	fn filterable_partition_consistency(x: Vec<i32>) -> bool {
2259		let p = |i: i32| i % 2 == 0;
2260		let either_bool = |i| if p(i) { Ok(i) } else { Err(i) };
2261
2262		let (not_satisfied, satisfied) = partition::<VecBrand, _>(p, x.clone());
2263		let (errs, oks) = partition_map::<VecBrand, _, _, _>(either_bool, x);
2264
2265		satisfied == oks && not_satisfied == errs
2266	}
2267
2268	// Witherable Laws
2269
2270	/// Tests `wither (pure <<< Just) ≡ pure`.
2271	#[quickcheck]
2272	fn witherable_identity(x: Vec<i32>) -> bool {
2273		wither::<VecBrand, OptionBrand, _, _>(|i| Some(Some(i)), x.clone()) == Some(x)
2274	}
2275
2276	/// Tests `wilt p ≡ map separate <<< traverse p`.
2277	#[quickcheck]
2278	fn witherable_wilt_consistency(x: Vec<i32>) -> bool {
2279		let p = |i: i32| Some(if i % 2 == 0 { Ok(i) } else { Err(i) });
2280
2281		let lhs = wilt::<VecBrand, OptionBrand, _, _, _>(p, x.clone());
2282		let rhs = crate::classes::functor::map::<OptionBrand, _, _>(
2283			separate::<VecBrand, _, _>,
2284			traverse::<VecBrand, _, _, OptionBrand>(p, x),
2285		);
2286
2287		lhs == rhs
2288	}
2289
2290	/// Tests `wither p ≡ map compact <<< traverse p`.
2291	#[quickcheck]
2292	fn witherable_wither_consistency(x: Vec<i32>) -> bool {
2293		let p = |i: i32| Some(if i % 2 == 0 { Some(i) } else { None });
2294
2295		let lhs = wither::<VecBrand, OptionBrand, _, _>(p, x.clone());
2296		let rhs = crate::classes::functor::map::<OptionBrand, _, _>(
2297			compact::<VecBrand, _>,
2298			traverse::<VecBrand, _, _, OptionBrand>(p, x),
2299		);
2300
2301		lhs == rhs
2302	}
2303
2304	// Alt Laws
2305
2306	/// Tests the associativity law for Alt.
2307	#[quickcheck]
2308	fn alt_associativity(
2309		x: Vec<i32>,
2310		y: Vec<i32>,
2311		z: Vec<i32>,
2312	) -> bool {
2313		alt::<VecBrand, _>(alt::<VecBrand, _>(x.clone(), y.clone()), z.clone())
2314			== alt::<VecBrand, _>(x, alt::<VecBrand, _>(y, z))
2315	}
2316
2317	/// Tests the distributivity law for Alt.
2318	#[quickcheck]
2319	fn alt_distributivity(
2320		x: Vec<i32>,
2321		y: Vec<i32>,
2322	) -> bool {
2323		let f = |i: i32| i.wrapping_mul(2).wrapping_add(1);
2324		map::<VecBrand, _, _>(f, alt::<VecBrand, _>(x.clone(), y.clone()))
2325			== alt::<VecBrand, _>(map::<VecBrand, _, _>(f, x), map::<VecBrand, _, _>(f, y))
2326	}
2327
2328	// Plus Laws
2329
2330	/// Tests the left identity law for Plus.
2331	#[quickcheck]
2332	fn plus_left_identity(x: Vec<i32>) -> bool {
2333		alt::<VecBrand, _>(plus_empty::<VecBrand, i32>(), x.clone()) == x
2334	}
2335
2336	/// Tests the right identity law for Plus.
2337	#[quickcheck]
2338	fn plus_right_identity(x: Vec<i32>) -> bool {
2339		alt::<VecBrand, _>(x.clone(), plus_empty::<VecBrand, i32>()) == x
2340	}
2341
2342	/// Tests the annihilation law for Plus.
2343	#[test]
2344	fn plus_annihilation() {
2345		let f = |i: i32| i.wrapping_mul(2);
2346		assert_eq!(
2347			map::<VecBrand, _, _>(f, plus_empty::<VecBrand, i32>()),
2348			plus_empty::<VecBrand, i32>(),
2349		);
2350	}
2351
2352	// Compactable Laws (Plus-dependent)
2353
2354	/// Tests the functor identity law for Compactable.
2355	#[quickcheck]
2356	fn compactable_functor_identity(fa: Vec<i32>) -> bool {
2357		compact::<VecBrand, _>(map::<VecBrand, _, _>(Some, fa.clone())) == fa
2358	}
2359
2360	/// Tests the Plus annihilation (empty) law for Compactable.
2361	#[test]
2362	fn compactable_plus_annihilation_empty() {
2363		assert_eq!(
2364			compact::<VecBrand, _>(plus_empty::<VecBrand, Option<i32>>()),
2365			plus_empty::<VecBrand, i32>(),
2366		);
2367	}
2368
2369	/// Tests the Plus annihilation (map) law for Compactable.
2370	#[quickcheck]
2371	fn compactable_plus_annihilation_map(xs: Vec<i32>) -> bool {
2372		compact::<VecBrand, _>(map::<VecBrand, _, _>(|_: i32| None::<i32>, xs))
2373			== plus_empty::<VecBrand, i32>()
2374	}
2375
2376	// Edge Cases
2377
2378	/// Tests `compact` on an empty vector.
2379	#[test]
2380	fn compact_empty() {
2381		assert_eq!(compact::<VecBrand, i32>(vec![] as Vec<Option<i32>>), vec![] as Vec<i32>);
2382	}
2383
2384	/// Tests `compact` on a vector with `None`.
2385	#[test]
2386	fn compact_with_none() {
2387		assert_eq!(compact::<VecBrand, i32>(vec![Some(1), None, Some(2)]), vec![1, 2]);
2388	}
2389
2390	/// Tests `separate` on an empty vector.
2391	#[test]
2392	fn separate_empty() {
2393		let (errs, oks) = separate::<VecBrand, i32, i32>(vec![] as Vec<Result<i32, i32>>);
2394		assert_eq!(oks, vec![] as Vec<i32>);
2395		assert_eq!(errs, vec![] as Vec<i32>);
2396	}
2397
2398	/// Tests `separate` on a vector with `Ok` and `Err`.
2399	#[test]
2400	fn separate_mixed() {
2401		let (errs, oks) = separate::<VecBrand, i32, i32>(vec![Ok(1), Err(2), Ok(3)]);
2402		assert_eq!(oks, vec![1, 3]);
2403		assert_eq!(errs, vec![2]);
2404	}
2405
2406	/// Tests `partition_map` on an empty vector.
2407	#[test]
2408	fn partition_map_empty() {
2409		let (errs, oks) =
2410			partition_map::<VecBrand, i32, i32, _>(|x: i32| Ok::<i32, i32>(x), vec![]);
2411		assert_eq!(oks, vec![] as Vec<i32>);
2412		assert_eq!(errs, vec![] as Vec<i32>);
2413	}
2414
2415	/// Tests `partition` on an empty vector.
2416	#[test]
2417	fn partition_empty() {
2418		let (not_satisfied, satisfied) = partition::<VecBrand, i32>(|x: i32| x > 0, vec![]);
2419		assert_eq!(satisfied, vec![] as Vec<i32>);
2420		assert_eq!(not_satisfied, vec![] as Vec<i32>);
2421	}
2422
2423	/// Tests `filter_map` on an empty vector.
2424	#[test]
2425	fn filter_map_empty() {
2426		assert_eq!(filter_map::<VecBrand, i32, _>(|x: i32| Some(x), vec![]), vec![] as Vec<i32>);
2427	}
2428
2429	/// Tests `filter` on an empty vector.
2430	#[test]
2431	fn filter_empty() {
2432		assert_eq!(filter::<VecBrand, i32>(|x: i32| x > 0, vec![]), vec![] as Vec<i32>);
2433	}
2434
2435	/// Tests `wilt` on an empty vector.
2436	#[test]
2437	fn wilt_empty() {
2438		let res = wilt::<VecBrand, OptionBrand, _, _, _>(|x: i32| Some(Ok::<i32, i32>(x)), vec![]);
2439		assert_eq!(res, Some((vec![], vec![])));
2440	}
2441
2442	/// Tests `wither` on an empty vector.
2443	#[test]
2444	fn wither_empty() {
2445		let res = wither::<VecBrand, OptionBrand, _, _>(|x: i32| Some(Some(x)), vec![]);
2446		assert_eq!(res, Some(vec![]));
2447	}
2448
2449	// Parallel Trait Laws
2450
2451	/// Verifies that `par_fold_map` correctly sums a large vector (100,000 elements).
2452	#[test]
2453	fn test_large_vector_par_fold_map() {
2454		use crate::types::Additive;
2455
2456		let xs: Vec<i32> = (0 .. 100000).collect();
2457		let res = par_fold_map::<VecBrand, _, _>(|x: i32| Additive(x as i64), xs);
2458		assert_eq!(res, Additive(4999950000));
2459	}
2460
2461	/// Property: `par_map` agrees with sequential `map`.
2462	#[quickcheck]
2463	fn prop_par_map_equals_map(xs: Vec<i32>) -> bool {
2464		let f = |x: i32| x.wrapping_add(1);
2465		let seq_res = map::<VecBrand, _, _>(f, xs.clone());
2466		let par_res = par_map::<VecBrand, _, _>(f, xs);
2467		seq_res == par_res
2468	}
2469
2470	/// Property: `par_fold_map` agrees with sequential `fold_map`.
2471	#[quickcheck]
2472	fn prop_par_fold_map_equals_fold_map(xs: Vec<i32>) -> bool {
2473		use crate::types::Additive;
2474
2475		let f = |x: i32| Additive(x as i64);
2476		let seq_res = crate::classes::foldable::fold_map::<crate::brands::RcFnBrand, VecBrand, _, _>(
2477			f,
2478			xs.clone(),
2479		);
2480		let par_res = par_fold_map::<VecBrand, _, _>(f, xs);
2481		seq_res == par_res
2482	}
2483
2484	/// Property: `par_fold_map` on an empty vector returns the Monoid's empty value.
2485	#[quickcheck]
2486	fn prop_par_fold_map_empty_is_empty(xs: Vec<i32>) -> bool {
2487		use crate::types::Additive;
2488
2489		if !xs.is_empty() {
2490			return true;
2491		}
2492		let par_res = par_fold_map::<VecBrand, _, _>(|x: i32| Additive(x as i64), xs);
2493		par_res == empty::<Additive<i64>>()
2494	}
2495
2496	// MonadRec tests
2497
2498	/// Tests the MonadRec identity law: `tail_rec_m(|a| pure(Done(a)), x) == pure(x)`.
2499	#[quickcheck]
2500	fn monad_rec_identity(x: i32) -> bool {
2501		use {
2502			crate::classes::monad_rec::tail_rec_m,
2503			core::ops::ControlFlow,
2504		};
2505		tail_rec_m::<VecBrand, _, _>(|a| vec![ControlFlow::Break(a)], x) == vec![x]
2506	}
2507
2508	/// Tests a simple linear recursion via `tail_rec_m`.
2509	#[test]
2510	fn monad_rec_linear() {
2511		use {
2512			crate::classes::monad_rec::tail_rec_m,
2513			core::ops::ControlFlow,
2514		};
2515		// Count up to 5
2516		let result = tail_rec_m::<VecBrand, _, _>(
2517			|n| {
2518				if n < 5 { vec![ControlFlow::Continue(n + 1)] } else { vec![ControlFlow::Break(n)] }
2519			},
2520			0,
2521		);
2522		assert_eq!(result, vec![5]);
2523	}
2524
2525	/// Tests branching nondeterminism via `tail_rec_m`.
2526	#[test]
2527	fn monad_rec_branching() {
2528		use {
2529			crate::classes::monad_rec::tail_rec_m,
2530			core::ops::ControlFlow,
2531		};
2532		// Each step either finishes or continues
2533		let result = tail_rec_m::<VecBrand, _, _>(
2534			|n: i32| {
2535				if n < 2 {
2536					vec![ControlFlow::Continue(n + 1), ControlFlow::Break(n * 100)]
2537				} else {
2538					vec![ControlFlow::Break(n * 100)]
2539				}
2540			},
2541			0,
2542		);
2543		// n=0: Loop(1), Done(0)
2544		// n=1: Loop(2), Done(100)
2545		// n=2: Done(200)
2546		assert_eq!(result, vec![0, 100, 200]);
2547	}
2548
2549	/// Tests that `tail_rec_m` handles an empty result from the step function.
2550	#[test]
2551	fn monad_rec_empty() {
2552		use {
2553			crate::classes::monad_rec::tail_rec_m,
2554			core::ops::ControlFlow,
2555		};
2556		let result: Vec<i32> =
2557			tail_rec_m::<VecBrand, _, _>(|_n| Vec::<ControlFlow<i32, i32>>::new(), 0);
2558		assert_eq!(result, Vec::<i32>::new());
2559	}
2560
2561	// Extend Laws
2562
2563	/// Tests basic `extend` on `Vec`: sum of suffixes.
2564	#[test]
2565	fn extend_sum_of_suffixes() {
2566		use crate::classes::extend::extend;
2567		let result = extend::<VecBrand, _, _>(|v: Vec<i32>| v.iter().sum::<i32>(), vec![1, 2, 3]);
2568		assert_eq!(result, vec![6, 5, 3]);
2569	}
2570
2571	/// Extend associativity: `extend(f, extend(g, w)) == extend(|w| f(extend(g, w)), w)`.
2572	#[quickcheck]
2573	fn extend_associativity(w: Vec<i32>) -> bool {
2574		use crate::classes::extend::extend;
2575		let g = |v: Vec<i32>| v.iter().fold(0i32, |a, b| a.wrapping_mul(2).wrapping_add(*b));
2576		let f = |v: Vec<i32>| v.iter().fold(0i32, |a, b| a.wrapping_add(b.wrapping_add(1)));
2577		let lhs = extend::<VecBrand, _, _>(f, extend::<VecBrand, _, _>(g, w.clone()));
2578		let rhs = extend::<VecBrand, _, _>(|w: Vec<i32>| f(extend::<VecBrand, _, _>(g, w)), w);
2579		lhs == rhs
2580	}
2581
2582	/// Tests that `duplicate` produces suffixes.
2583	#[test]
2584	fn extend_duplicate_suffixes() {
2585		use crate::classes::extend::duplicate;
2586		let result = duplicate::<VecBrand, _>(vec![1, 2, 3]);
2587		assert_eq!(result, vec![vec![1, 2, 3], vec![2, 3], vec![3]]);
2588	}
2589
2590	/// Tests `extend` on an empty vector.
2591	#[test]
2592	fn extend_empty() {
2593		use crate::classes::extend::extend;
2594		let result =
2595			extend::<VecBrand, _, _>(|v: Vec<i32>| v.iter().sum::<i32>(), Vec::<i32>::new());
2596		assert_eq!(result, Vec::<i32>::new());
2597	}
2598
2599	/// Tests `extend` on a singleton vector.
2600	#[test]
2601	fn extend_singleton() {
2602		use crate::classes::extend::extend;
2603		let result = extend::<VecBrand, _, _>(|v: Vec<i32>| v.iter().sum::<i32>(), vec![42]);
2604		assert_eq!(result, vec![42]);
2605	}
2606}