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. The corresponding brand is [`VecBrand`](crate::brands::VecBrand).
4
5#[fp_macros::document_module]
6mod inner {
7	use {
8		crate::{
9			Apply,
10			brands::{
11				OptionBrand,
12				VecBrand,
13			},
14			classes::*,
15			dispatch::Ref,
16			impl_kind,
17			kinds::*,
18		},
19		core::ops::ControlFlow,
20		fp_macros::*,
21	};
22
23	impl_kind! {
24		for VecBrand {
25			type Of<'a, A: 'a>: 'a = Vec<A>;
26		}
27	}
28
29	impl VecBrand {
30		/// Constructs a new vector by prepending a value to an existing vector.
31		///
32		/// This method creates a new vector with the given head element followed by the elements of the tail vector.
33		#[document_signature]
34		///
35		#[document_type_parameters("The type of the elements in the vector.")]
36		///
37		#[document_parameters(
38			"A value to prepend to the vector.",
39			"A vector to prepend the value to."
40		)]
41		///
42		#[document_returns(
43			"A new vector consisting of the `head` element prepended to the `tail` vector."
44		)]
45		#[document_examples]
46		///
47		/// ```
48		/// use fp_library::brands::VecBrand;
49		///
50		/// let head = 1;
51		/// let tail = vec![2, 3];
52		/// let new_vec = VecBrand::construct(head, tail);
53		/// assert_eq!(new_vec, vec![1, 2, 3]);
54		///
55		/// let empty_tail = vec![];
56		/// let single_element = VecBrand::construct(42, empty_tail);
57		/// assert_eq!(single_element, vec![42]);
58		/// ```
59		pub fn construct<A>(
60			head: A,
61			tail: Vec<A>,
62		) -> Vec<A>
63		where
64			A: Clone, {
65			[vec![head], tail].concat()
66		}
67
68		/// Deconstructs a slice into its head element and tail vector.
69		///
70		/// This method splits a slice into its first element and the rest of the elements as a new vector.
71		#[document_signature]
72		///
73		#[document_type_parameters("The type of the elements in the vector.")]
74		///
75		#[document_parameters("The vector slice to deconstruct.")]
76		///
77		#[document_returns(
78			"An [`Option`] containing a tuple of the head element and the remaining tail vector, or [`None`] if the slice is empty."
79		)]
80		///
81		#[document_examples]
82		///
83		/// ```
84		/// use fp_library::brands::VecBrand;
85		///
86		/// let vec = vec![1, 2, 3];
87		/// let deconstructed = VecBrand::deconstruct(&vec);
88		/// assert_eq!(deconstructed, Some((1, vec![2, 3])));
89		///
90		/// let empty: Vec<i32> = vec![];
91		/// assert_eq!(VecBrand::deconstruct(&empty), None);
92		/// ```
93		pub fn deconstruct<A>(slice: &[A]) -> Option<(A, Vec<A>)>
94		where
95			A: Clone, {
96			match slice {
97				[] => None,
98				[head, tail @ ..] => Some((head.clone(), tail.to_vec())),
99			}
100		}
101	}
102
103	impl Functor for VecBrand {
104		/// Maps a function over the vector.
105		///
106		/// This method applies a function to each element of the vector, producing a new vector with the transformed values.
107		#[document_signature]
108		///
109		#[document_type_parameters(
110			"The lifetime of the elements.",
111			"The type of the elements in the vector.",
112			"The type of the elements in the resulting vector."
113		)]
114		///
115		#[document_parameters("The function to apply to each element.", "The vector to map over.")]
116		///
117		#[document_returns("A new vector containing the results of applying the function.")]
118		///
119		#[document_examples]
120		///
121		/// ```
122		/// use fp_library::{
123		/// 	brands::*,
124		/// 	functions::*,
125		/// };
126		///
127		/// assert_eq!(explicit::map::<VecBrand, _, _, _, _>(|x: i32| x * 2, vec![1, 2, 3]), vec![2, 4, 6]);
128		/// ```
129		fn map<'a, A: 'a, B: 'a>(
130			func: impl Fn(A) -> B + 'a,
131			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
132		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
133			fa.into_iter().map(func).collect()
134		}
135	}
136
137	impl Lift for VecBrand {
138		/// Lifts a binary function into the vector context (Cartesian product).
139		///
140		/// This method applies a binary function to all pairs of elements from two vectors, producing a new vector containing the results (Cartesian product).
141		#[document_signature]
142		///
143		#[document_type_parameters(
144			"The lifetime of the elements.",
145			"The type of the elements in the first vector.",
146			"The type of the elements in the second vector.",
147			"The type of the elements in the resulting vector."
148		)]
149		///
150		#[document_parameters(
151			"The binary function to apply.",
152			"The first vector.",
153			"The second vector."
154		)]
155		///
156		#[document_returns(
157			"A new vector containing the results of applying the function to all pairs of elements."
158		)]
159		#[document_examples]
160		///
161		/// ```
162		/// use fp_library::{
163		/// 	brands::*,
164		/// 	functions::*,
165		/// };
166		///
167		/// assert_eq!(
168		/// 	explicit::lift2::<VecBrand, _, _, _, _, _, _>(|x, y| x + y, vec![1, 2], vec![10, 20]),
169		/// 	vec![11, 21, 12, 22]
170		/// );
171		/// ```
172		fn lift2<'a, A, B, C>(
173			func: impl Fn(A, B) -> C + 'a,
174			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
175			fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
176		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
177		where
178			A: Clone + 'a,
179			B: Clone + 'a,
180			C: 'a, {
181			fa.iter().flat_map(|a| fb.iter().map(|b| func(a.clone(), b.clone()))).collect()
182		}
183	}
184
185	impl Pointed for VecBrand {
186		/// Wraps a value in a vector.
187		///
188		/// This method creates a new vector containing the single given value.
189		#[document_signature]
190		///
191		#[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
192		///
193		#[document_parameters("The value to wrap.")]
194		///
195		#[document_returns("A vector containing the single value.")]
196		///
197		#[document_examples]
198		///
199		/// ```
200		/// use fp_library::{
201		/// 	brands::VecBrand,
202		/// 	functions::*,
203		/// };
204		///
205		/// assert_eq!(pure::<VecBrand, _>(5), vec![5]);
206		/// ```
207		fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
208			vec![a]
209		}
210	}
211
212	impl ApplyFirst for VecBrand {}
213	impl ApplySecond for VecBrand {}
214
215	impl Semiapplicative for VecBrand {
216		/// Applies wrapped functions to wrapped values (Cartesian product).
217		///
218		/// This method applies each function in the first vector to each value in the second vector, producing a new vector containing all the results.
219		#[document_signature]
220		///
221		#[document_type_parameters(
222			"The lifetime of the values.",
223			"The brand of the cloneable function wrapper.",
224			"The type of the input values.",
225			"The type of the output values."
226		)]
227		///
228		#[document_parameters(
229			"The vector containing the functions.",
230			"The vector containing the values."
231		)]
232		///
233		#[document_returns(
234			"A new vector containing the results of applying each function to each value."
235		)]
236		#[document_examples]
237		///
238		/// ```
239		/// use fp_library::{
240		/// 	brands::*,
241		/// 	classes::*,
242		/// 	functions::*,
243		/// };
244		///
245		/// let funcs = vec![
246		/// 	lift_fn_new::<RcFnBrand, _, _>(|x: i32| x + 1),
247		/// 	lift_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2),
248		/// ];
249		/// assert_eq!(apply(funcs, vec![1, 2]), vec![2, 3, 2, 4]);
250		/// ```
251		fn apply<'a, FnBrand: 'a + CloneFn, A: 'a + Clone, B: 'a>(
252			ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneFn>::Of<'a, A, B>>),
253			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
254		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
255			ff.iter().flat_map(|f| fa.iter().map(move |a| f(a.clone()))).collect()
256		}
257	}
258
259	impl Semimonad for VecBrand {
260		/// Chains vector computations (`flat_map`).
261		///
262		/// This method applies a function that returns a vector to each element of the input vector, and then flattens the result.
263		#[document_signature]
264		///
265		#[document_type_parameters(
266			"The lifetime of the elements.",
267			"The type of the elements in the input vector.",
268			"The type of the elements in the output vector."
269		)]
270		///
271		#[document_parameters(
272			"The first vector.",
273			"The function to apply to each element, returning a vector."
274		)]
275		///
276		#[document_returns("A new vector containing the flattened results.")]
277		#[document_examples]
278		///
279		/// ```
280		/// use fp_library::{
281		/// 	brands::VecBrand,
282		/// 	functions::*,
283		/// };
284		///
285		/// assert_eq!(
286		/// 	explicit::bind::<VecBrand, _, _, _, _>(vec![1, 2], |x| vec![x, x * 2]),
287		/// 	vec![1, 2, 2, 4]
288		/// );
289		/// ```
290		fn bind<'a, A: 'a, B: 'a>(
291			ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
292			func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
293		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
294			ma.into_iter().flat_map(func).collect()
295		}
296	}
297
298	impl Alt for VecBrand {
299		/// Concatenates two vectors.
300		///
301		/// This is the same as [`Semigroup::append`] for `Vec`, providing an
302		/// associative choice operation for the `Vec` type constructor.
303		#[document_signature]
304		///
305		#[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
306		///
307		#[document_parameters("The first vector.", "The second vector.")]
308		///
309		#[document_returns("The concatenated vector.")]
310		#[document_examples]
311		///
312		/// ```
313		/// use fp_library::{
314		/// 	brands::*,
315		/// 	classes::*,
316		/// 	functions::*,
317		/// };
318		///
319		/// let x = vec![1, 2];
320		/// let y = vec![3, 4];
321		/// assert_eq!(explicit::alt::<VecBrand, _, _, _>(x, y), vec![1, 2, 3, 4]);
322		/// ```
323		fn alt<'a, A: 'a>(
324			fa1: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
325			fa2: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
326		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
327			let mut result = fa1;
328			result.extend(fa2);
329			result
330		}
331	}
332
333	impl RefAlt for VecBrand {
334		/// Concatenates two vectors by reference.
335		///
336		/// Both input vectors are borrowed and their elements are cloned to
337		/// construct a new vector containing all elements from both inputs.
338		/// This is the by-reference counterpart of [`Alt::alt`] for `Vec`.
339		#[document_signature]
340		///
341		#[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
342		///
343		#[document_parameters("The first vector.", "The second vector.")]
344		///
345		#[document_returns("A new vector containing cloned elements from both inputs.")]
346		#[document_examples]
347		///
348		/// ```
349		/// use fp_library::{
350		/// 	brands::*,
351		/// 	classes::*,
352		/// 	functions::*,
353		/// };
354		///
355		/// let x = vec![1, 2];
356		/// let y = vec![3, 4];
357		/// assert_eq!(explicit::alt::<VecBrand, _, _, _>(&x, &y), vec![1, 2, 3, 4]);
358		/// ```
359		fn ref_alt<'a, A: 'a + Clone>(
360			fa1: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
361			fa2: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
362		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
363			fa1.iter().chain(fa2.iter()).cloned().collect()
364		}
365	}
366
367	impl Plus for VecBrand {
368		/// Returns an empty vector, the identity element for [`alt`](Alt::alt).
369		#[document_signature]
370		///
371		#[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
372		///
373		#[document_returns("An empty vector.")]
374		#[document_examples]
375		///
376		/// ```
377		/// use fp_library::{
378		/// 	brands::*,
379		/// 	functions::*,
380		/// };
381		///
382		/// let x: Vec<i32> = plus_empty::<VecBrand, i32>();
383		/// assert_eq!(x, vec![]);
384		/// ```
385		fn empty<'a, A: 'a>() -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
386			Vec::new()
387		}
388	}
389
390	impl Foldable for VecBrand {
391		/// Folds the vector from the right.
392		///
393		/// This method performs a right-associative fold of the vector.
394		#[document_signature]
395		///
396		#[document_type_parameters(
397			"The lifetime of the elements.",
398			"The brand of the cloneable function to use.",
399			"The type of the elements in the vector.",
400			"The type of the accumulator."
401		)]
402		///
403		#[document_parameters("The folding function.", "The initial value.", "The vector to fold.")]
404		///
405		#[document_returns("The final accumulator value.")]
406		///
407		#[document_examples]
408		///
409		/// ```
410		/// use fp_library::{
411		/// 	brands::*,
412		/// 	functions::*,
413		/// };
414		///
415		/// assert_eq!(
416		/// 	explicit::fold_right::<RcFnBrand, VecBrand, _, _, _, _>(
417		/// 		|x: i32, acc| x + acc,
418		/// 		0,
419		/// 		vec![1, 2, 3]
420		/// 	),
421		/// 	6
422		/// );
423		/// ```
424		fn fold_right<'a, FnBrand, A: 'a + Clone, B: 'a>(
425			func: impl Fn(A, B) -> B + 'a,
426			initial: B,
427			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
428		) -> B
429		where
430			FnBrand: CloneFn + 'a, {
431			fa.into_iter().rev().fold(initial, |acc, x| func(x, acc))
432		}
433
434		/// Folds the vector from the left.
435		///
436		/// This method performs a left-associative fold of the vector.
437		#[document_signature]
438		///
439		#[document_type_parameters(
440			"The lifetime of the elements.",
441			"The brand of the cloneable function to use.",
442			"The type of the elements in the vector.",
443			"The type of the accumulator."
444		)]
445		///
446		#[document_parameters(
447			"The function to apply to the accumulator and each element.",
448			"The initial value of the accumulator.",
449			"The vector to fold."
450		)]
451		///
452		#[document_returns("The final accumulator value.")]
453		#[document_examples]
454		///
455		/// ```
456		/// use fp_library::{
457		/// 	brands::*,
458		/// 	functions::*,
459		/// };
460		///
461		/// assert_eq!(
462		/// 	explicit::fold_left::<RcFnBrand, VecBrand, _, _, _, _>(
463		/// 		|acc, x: i32| acc + x,
464		/// 		0,
465		/// 		vec![1, 2, 3]
466		/// 	),
467		/// 	6
468		/// );
469		/// ```
470		fn fold_left<'a, FnBrand, A: 'a + Clone, B: 'a>(
471			func: impl Fn(B, A) -> B + 'a,
472			initial: B,
473			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
474		) -> B
475		where
476			FnBrand: CloneFn + 'a, {
477			fa.into_iter().fold(initial, func)
478		}
479
480		/// Maps the values to a monoid and combines them.
481		///
482		/// This method maps each element of the vector to a monoid and then combines the results using the monoid's `append` operation.
483		#[document_signature]
484		///
485		#[document_type_parameters(
486			"The lifetime of the elements.",
487			"The brand of the cloneable function to use.",
488			"The type of the elements in the vector.",
489			"The type of the monoid."
490		)]
491		///
492		#[document_parameters("The mapping function.", "The vector to fold.")]
493		///
494		#[document_returns("The combined monoid value.")]
495		///
496		#[document_examples]
497		///
498		/// ```
499		/// use fp_library::{
500		/// 	brands::*,
501		/// 	functions::*,
502		/// };
503		///
504		/// assert_eq!(
505		/// 	explicit::fold_map::<RcFnBrand, VecBrand, _, _, _, _>(
506		/// 		|x: i32| x.to_string(),
507		/// 		vec![1, 2, 3]
508		/// 	),
509		/// 	"123".to_string()
510		/// );
511		/// ```
512		fn fold_map<'a, FnBrand, A: 'a + Clone, M>(
513			func: impl Fn(A) -> M + 'a,
514			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
515		) -> M
516		where
517			M: Monoid + 'a,
518			FnBrand: CloneFn + 'a, {
519			fa.into_iter().map(func).fold(M::empty(), |acc, x| M::append(acc, x))
520		}
521	}
522
523	impl Traversable for VecBrand {
524		/// Traverses the vector with an applicative function.
525		///
526		/// This method maps each element of the vector to a computation, evaluates them, and combines the results into an applicative context.
527		#[document_signature]
528		///
529		#[document_type_parameters(
530			"The lifetime of the elements.",
531			"The type of the elements in the traversable structure.",
532			"The type of the elements in the resulting traversable structure.",
533			"The applicative context."
534		)]
535		///
536		#[document_parameters(
537			"The function to apply to each element, returning a value in an applicative context.",
538			"The vector to traverse."
539		)]
540		///
541		#[document_returns("The vector wrapped in the applicative context.")]
542		#[document_examples]
543		///
544		/// ```
545		/// use fp_library::{
546		/// 	brands::*,
547		/// 	functions::*,
548		/// };
549		///
550		/// assert_eq!(
551		/// 	explicit::traverse::<RcFnBrand, VecBrand, _, _, OptionBrand, _, _>(
552		/// 		|x| Some(x * 2),
553		/// 		vec![1, 2, 3]
554		/// 	),
555		/// 	Some(vec![2, 4, 6])
556		/// );
557		/// ```
558		fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
559			func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
560			ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
561		) -> 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>)>)
562		where
563			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
564			Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
565			let len = ta.len();
566			ta.into_iter().fold(F::pure(Vec::with_capacity(len)), |acc, x| {
567				F::lift2(
568					|mut v, b| {
569						v.push(b);
570						v
571					},
572					acc,
573					func(x),
574				)
575			})
576		}
577
578		/// Sequences a vector of applicative.
579		///
580		/// This method evaluates the computations inside the vector and accumulates the results into an applicative context.
581		#[document_signature]
582		///
583		#[document_type_parameters(
584			"The lifetime of the elements.",
585			"The type of the elements in the traversable structure.",
586			"The applicative context."
587		)]
588		///
589		#[document_parameters("The vector containing the applicative values.")]
590		///
591		#[document_returns("The vector wrapped in the applicative context.")]
592		///
593		#[document_examples]
594		///
595		/// ```
596		/// use fp_library::{
597		/// 	brands::{
598		/// 		OptionBrand,
599		/// 		VecBrand,
600		/// 	},
601		/// 	functions::*,
602		/// };
603		///
604		/// assert_eq!(sequence::<VecBrand, _, OptionBrand>(vec![Some(1), Some(2)]), Some(vec![1, 2]));
605		/// ```
606		fn sequence<'a, A: 'a + Clone, F: Applicative>(
607			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>)>)
608		) -> 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>)>)
609		where
610			Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
611			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
612			let len = ta.len();
613			ta.into_iter().fold(F::pure(Vec::with_capacity(len)), |acc, x| {
614				F::lift2(
615					|mut v, a| {
616						v.push(a);
617						v
618					},
619					acc,
620					x,
621				)
622			})
623		}
624	}
625
626	impl WithIndex for VecBrand {
627		type Index = usize;
628	}
629
630	impl FunctorWithIndex for VecBrand {
631		/// Maps a function over the vector, providing the index of each element.
632		#[document_signature]
633		#[document_type_parameters(
634			"The lifetime of the elements.",
635			"The type of the elements in the vector.",
636			"The type of the elements in the resulting vector."
637		)]
638		#[document_parameters(
639			"The function to apply to each element and its index.",
640			"The vector to map over."
641		)]
642		#[document_returns("A new vector containing the results of applying the function.")]
643		#[document_examples]
644		///
645		/// ```
646		/// use fp_library::{
647		/// 	brands::VecBrand,
648		/// 	functions::*,
649		/// };
650		/// let v = vec![10, 20, 30];
651		/// // Use `map_with_index` via the method on the trait, or a helper function if one existed.
652		/// // Since there's no helper function in `functions.rs` yet, we use explicit syntax or call it via trait.
653		/// use fp_library::classes::functor_with_index::FunctorWithIndex;
654		/// let mapped = <VecBrand as FunctorWithIndex>::map_with_index(|i, x| x + i as i32, v);
655		/// assert_eq!(mapped, vec![10, 21, 32]);
656		/// ```
657		fn map_with_index<'a, A: 'a, B: 'a>(
658			f: impl Fn(usize, A) -> B + 'a,
659			fa: Vec<A>,
660		) -> Vec<B> {
661			fa.into_iter().enumerate().map(|(i, a)| f(i, a)).collect()
662		}
663	}
664
665	impl FoldableWithIndex for VecBrand {
666		/// Folds the vector using a monoid, providing the index of each element.
667		#[document_signature]
668		#[document_type_parameters(
669			"The lifetime of the elements.",
670			"The brand of the cloneable function to use.",
671			"The type of the elements in the vector.",
672			"The monoid type."
673		)]
674		#[document_parameters(
675			"The function to apply to each element and its index.",
676			"The vector to fold."
677		)]
678		#[document_returns("The combined monoid value.")]
679		#[document_examples]
680		///
681		/// ```
682		/// use fp_library::{
683		/// 	brands::*,
684		/// 	classes::foldable_with_index::FoldableWithIndex,
685		/// 	functions::*,
686		/// };
687		/// let v = vec![10, 20, 30];
688		/// let s = <VecBrand as FoldableWithIndex>::fold_map_with_index::<RcFnBrand, _, _>(
689		/// 	|i, x| format!("{}:{}", i, x),
690		/// 	v,
691		/// );
692		/// assert_eq!(s, "0:101:202:30");
693		/// ```
694		fn fold_map_with_index<'a, FnBrand, A: 'a + Clone, R: Monoid + 'a>(
695			f: impl Fn(usize, A) -> R + 'a,
696			fa: Vec<A>,
697		) -> R
698		where
699			FnBrand: LiftFn + 'a, {
700			fa.into_iter()
701				.enumerate()
702				.map(|(i, a)| f(i, a))
703				.fold(R::empty(), |acc, x| R::append(acc, x))
704		}
705	}
706
707	impl TraversableWithIndex for VecBrand {
708		/// Traverses the vector with an applicative function, providing the index of each element.
709		#[document_signature]
710		#[document_type_parameters(
711			"The lifetime of the elements.",
712			"The type of the elements in the vector.",
713			"The type of the elements in the resulting vector.",
714			"The applicative context."
715		)]
716		#[document_parameters(
717			"The function to apply to each element and its index, returning a value in an applicative context.",
718			"The vector to traverse."
719		)]
720		#[document_returns("The vector wrapped in the applicative context.")]
721		#[document_examples]
722		///
723		/// ```
724		/// use fp_library::{
725		/// 	brands::{
726		/// 		OptionBrand,
727		/// 		VecBrand,
728		/// 	},
729		/// 	classes::traversable_with_index::TraversableWithIndex,
730		/// 	functions::*,
731		/// };
732		/// let v = vec![10, 20, 30];
733		/// let t = <VecBrand as TraversableWithIndex>::traverse_with_index::<i32, i32, OptionBrand>(
734		/// 	|i, x| Some(x + i as i32),
735		/// 	v,
736		/// );
737		/// assert_eq!(t, Some(vec![10, 21, 32]));
738		/// ```
739		fn traverse_with_index<'a, A: 'a, B: 'a + Clone, M: Applicative>(
740			f: impl Fn(usize, A) -> M::Of<'a, B> + 'a,
741			ta: Vec<A>,
742		) -> M::Of<'a, Vec<B>> {
743			let len = ta.len();
744			ta.into_iter().enumerate().fold(M::pure(Vec::with_capacity(len)), |acc, (i, x)| {
745				M::lift2(
746					|mut v, b| {
747						v.push(b);
748						v
749					},
750					acc,
751					f(i, x),
752				)
753			})
754		}
755	}
756
757	#[document_type_parameters("The type of the elements in the vector.")]
758	impl<A: Clone> Semigroup for Vec<A> {
759		/// Appends one vector to another.
760		///
761		/// This method concatenates two vectors.
762		#[document_signature]
763		///
764		#[document_parameters("The first vector.", "The second vector.")]
765		///
766		#[document_returns("The concatenated vector.")]
767		///
768		#[document_examples]
769		///
770		/// ```
771		/// use fp_library::functions::*;
772		///
773		/// assert_eq!(append(vec![1, 2], vec![3, 4]), vec![1, 2, 3, 4]);
774		/// ```
775		fn append(
776			a: Self,
777			b: Self,
778		) -> Self {
779			[a, b].concat()
780		}
781	}
782
783	#[document_type_parameters("The type of the elements in the vector.")]
784	impl<A: Clone> Monoid for Vec<A> {
785		/// Returns an empty vector.
786		///
787		/// This method returns a new, empty vector.
788		#[document_signature]
789		///
790		#[document_returns("An empty vector.")]
791		///
792		#[document_examples]
793		///
794		/// ```
795		/// use fp_library::functions::*;
796		///
797		/// assert_eq!(empty::<Vec<i32>>(), vec![]);
798		/// ```
799		fn empty() -> Self {
800			Vec::new()
801		}
802	}
803
804	impl VecBrand {
805		/// Maps a function over the vector in parallel.
806		///
807		/// When the `rayon` feature is enabled, elements are processed across multiple threads.
808		/// Otherwise falls back to sequential mapping.
809		#[document_signature]
810		///
811		#[document_type_parameters(
812			"The lifetime of the elements.",
813			"The input element type.",
814			"The output element type."
815		)]
816		///
817		#[document_parameters(
818			"The function to apply to each element. Must be `Send + Sync`.",
819			"The vector to map over."
820		)]
821		///
822		#[document_returns("A new vector containing the mapped elements.")]
823		///
824		#[document_examples]
825		///
826		/// ```
827		/// use fp_library::brands::VecBrand;
828		///
829		/// let result = VecBrand::par_map(|x: i32| x * 2, vec![1, 2, 3]);
830		/// assert_eq!(result, vec![2, 4, 6]);
831		/// ```
832		pub fn par_map<'a, A: 'a + Send, B: 'a + Send>(
833			f: impl Fn(A) -> B + Send + Sync + 'a,
834			fa: Vec<A>,
835		) -> Vec<B> {
836			#[cfg(feature = "rayon")]
837			{
838				use rayon::prelude::*;
839				fa.into_par_iter().map(f).collect()
840			}
841			#[cfg(not(feature = "rayon"))]
842			fa.into_iter().map(f).collect()
843		}
844
845		/// Compacts a vector of options in parallel, discarding `None` values.
846		///
847		/// When the `rayon` feature is enabled, elements are processed across multiple threads.
848		/// Otherwise falls back to sequential compaction.
849		#[document_signature]
850		///
851		#[document_type_parameters("The lifetime of the elements.", "The element type.")]
852		///
853		#[document_parameters("The vector of options.")]
854		///
855		#[document_returns("A new vector containing the unwrapped `Some` values.")]
856		///
857		#[document_examples]
858		///
859		/// ```
860		/// use fp_library::brands::VecBrand;
861		///
862		/// let result = VecBrand::par_compact(vec![Some(1), None, Some(3)]);
863		/// assert_eq!(result, vec![1, 3]);
864		/// ```
865		pub fn par_compact<'a, A: 'a + Send>(fa: Vec<Option<A>>) -> Vec<A> {
866			#[cfg(feature = "rayon")]
867			{
868				use rayon::prelude::*;
869				fa.into_par_iter().flatten().collect()
870			}
871			#[cfg(not(feature = "rayon"))]
872			fa.into_iter().flatten().collect()
873		}
874
875		/// Separates a vector of results into `(errors, oks)` in parallel.
876		///
877		/// When the `rayon` feature is enabled, elements are processed across multiple threads.
878		/// Otherwise falls back to sequential separation.
879		#[document_signature]
880		///
881		#[document_type_parameters(
882			"The lifetime of the elements.",
883			"The error type.",
884			"The success type."
885		)]
886		///
887		#[document_parameters("The vector of results.")]
888		///
889		#[document_returns(
890			"A pair `(errs, oks)` where `errs` contains the `Err` values and `oks` the `Ok` values."
891		)]
892		///
893		#[document_examples]
894		///
895		/// ```
896		/// use fp_library::brands::VecBrand;
897		///
898		/// let v: Vec<Result<i32, &str>> = vec![Ok(1), Err("a"), Ok(3)];
899		/// let (errs, oks): (Vec<&str>, Vec<i32>) = VecBrand::par_separate(v);
900		/// assert_eq!(errs, vec!["a"]);
901		/// assert_eq!(oks, vec![1, 3]);
902		/// ```
903		pub fn par_separate<'a, E: 'a + Send, O: 'a + Send>(
904			fa: Vec<Result<O, E>>
905		) -> (Vec<E>, Vec<O>) {
906			#[cfg(feature = "rayon")]
907			{
908				use rayon::{
909					iter::Either,
910					prelude::*,
911				};
912				fa.into_par_iter().partition_map(|r| match r {
913					Ok(o) => Either::Right(o),
914					Err(e) => Either::Left(e),
915				})
916			}
917			#[cfg(not(feature = "rayon"))]
918			{
919				let mut errs = Vec::new();
920				let mut oks = Vec::new();
921				for result in fa {
922					match result {
923						Ok(o) => oks.push(o),
924						Err(e) => errs.push(e),
925					}
926				}
927				(errs, oks)
928			}
929		}
930
931		/// Maps and filters a vector in parallel, discarding elements where `f` returns `None`.
932		///
933		/// When the `rayon` feature is enabled, elements are processed across multiple threads.
934		/// Otherwise falls back to sequential filter-mapping.
935		#[document_signature]
936		///
937		#[document_type_parameters(
938			"The lifetime of the elements.",
939			"The input element type.",
940			"The output element type."
941		)]
942		///
943		#[document_parameters(
944			"The function to apply. Must be `Send + Sync`.",
945			"The vector to filter and map."
946		)]
947		///
948		#[document_returns("A new vector containing the `Some` results of applying `f`.")]
949		///
950		#[document_examples]
951		///
952		/// ```
953		/// use fp_library::brands::VecBrand;
954		///
955		/// let result = VecBrand::par_filter_map(
956		/// 	|x: i32| if x % 2 == 0 { Some(x * 10) } else { None },
957		/// 	vec![1, 2, 3, 4, 5],
958		/// );
959		/// assert_eq!(result, vec![20, 40]);
960		/// ```
961		pub fn par_filter_map<'a, A: 'a + Send, B: 'a + Send>(
962			f: impl Fn(A) -> Option<B> + Send + Sync + 'a,
963			fa: Vec<A>,
964		) -> Vec<B> {
965			#[cfg(feature = "rayon")]
966			{
967				use rayon::prelude::*;
968				fa.into_par_iter().filter_map(f).collect()
969			}
970			#[cfg(not(feature = "rayon"))]
971			fa.into_iter().filter_map(f).collect()
972		}
973
974		/// Filters a vector in parallel, retaining only elements satisfying `f`.
975		///
976		/// When the `rayon` feature is enabled, elements are processed across multiple threads.
977		/// Otherwise falls back to sequential filtering.
978		#[document_signature]
979		///
980		#[document_type_parameters("The lifetime of the elements.", "The element type.")]
981		///
982		#[document_parameters("The predicate. Must be `Send + Sync`.", "The vector to filter.")]
983		///
984		#[document_returns("A new vector containing only the elements satisfying `f`.")]
985		///
986		#[document_examples]
987		///
988		/// ```
989		/// use fp_library::brands::VecBrand;
990		///
991		/// let result = VecBrand::par_filter(|x: &i32| x % 2 == 0, vec![1, 2, 3, 4, 5]);
992		/// assert_eq!(result, vec![2, 4]);
993		/// ```
994		pub fn par_filter<'a, A: 'a + Send>(
995			f: impl Fn(&A) -> bool + Send + Sync + 'a,
996			fa: Vec<A>,
997		) -> Vec<A> {
998			#[cfg(feature = "rayon")]
999			{
1000				use rayon::prelude::*;
1001				fa.into_par_iter().filter(|a| f(a)).collect()
1002			}
1003			#[cfg(not(feature = "rayon"))]
1004			fa.into_iter().filter(|a| f(a)).collect()
1005		}
1006
1007		/// Maps each element to a [`Monoid`] value and combines them in parallel.
1008		///
1009		/// When the `rayon` feature is enabled, mapping and reduction happen across multiple threads.
1010		/// Otherwise falls back to sequential fold-map.
1011		#[document_signature]
1012		///
1013		#[document_type_parameters(
1014			"The lifetime of the elements.",
1015			"The element type.",
1016			"The monoid type."
1017		)]
1018		///
1019		#[document_parameters(
1020			"The function mapping each element to a monoid value. Must be `Send + Sync`.",
1021			"The vector to fold."
1022		)]
1023		///
1024		#[document_returns("The combined monoid value.")]
1025		///
1026		#[document_examples]
1027		///
1028		/// ```
1029		/// use fp_library::brands::VecBrand;
1030		///
1031		/// let result = VecBrand::par_fold_map(|x: i32| x.to_string(), vec![1, 2, 3]);
1032		/// assert_eq!(result, "123");
1033		/// ```
1034		pub fn par_fold_map<'a, A: 'a + Send, M: Monoid + Send + 'a>(
1035			f: impl Fn(A) -> M + Send + Sync + 'a,
1036			fa: Vec<A>,
1037		) -> M {
1038			#[cfg(feature = "rayon")]
1039			{
1040				use rayon::prelude::*;
1041				fa.into_par_iter().map(f).reduce(M::empty, |acc, m| M::append(acc, m))
1042			}
1043			#[cfg(not(feature = "rayon"))]
1044			fa.into_iter().map(f).fold(M::empty(), |acc, m| M::append(acc, m))
1045		}
1046
1047		/// Maps a function over the vector in parallel, providing each element's index.
1048		///
1049		/// When the `rayon` feature is enabled, elements are processed across multiple threads.
1050		/// Otherwise falls back to sequential indexed mapping.
1051		#[document_signature]
1052		///
1053		#[document_type_parameters(
1054			"The lifetime of the elements.",
1055			"The input element type.",
1056			"The output element type."
1057		)]
1058		///
1059		#[document_parameters(
1060			"The function to apply to each index and element. Must be `Send + Sync`.",
1061			"The vector to map over."
1062		)]
1063		///
1064		#[document_returns("A new vector containing the mapped elements.")]
1065		///
1066		#[document_examples]
1067		///
1068		/// ```
1069		/// use fp_library::brands::VecBrand;
1070		///
1071		/// let result = VecBrand::par_map_with_index(|i, x: i32| x + i as i32, vec![10, 20, 30]);
1072		/// assert_eq!(result, vec![10, 21, 32]);
1073		/// ```
1074		pub fn par_map_with_index<'a, A: 'a + Send, B: 'a + Send>(
1075			f: impl Fn(usize, A) -> B + Send + Sync + 'a,
1076			fa: Vec<A>,
1077		) -> Vec<B> {
1078			#[cfg(feature = "rayon")]
1079			{
1080				use rayon::prelude::*;
1081				fa.into_par_iter().enumerate().map(|(i, a)| f(i, a)).collect()
1082			}
1083			#[cfg(not(feature = "rayon"))]
1084			fa.into_iter().enumerate().map(|(i, a)| f(i, a)).collect()
1085		}
1086
1087		/// Maps each element and its index to a [`Monoid`] value and combines them in parallel.
1088		///
1089		/// When the `rayon` feature is enabled, mapping and reduction happen across multiple threads.
1090		/// Otherwise falls back to sequential indexed fold-map.
1091		#[document_signature]
1092		///
1093		#[document_type_parameters(
1094			"The lifetime of the elements.",
1095			"The element type.",
1096			"The monoid type."
1097		)]
1098		///
1099		#[document_parameters(
1100			"The function mapping each index and element to a monoid value. Must be `Send + Sync`.",
1101			"The vector to fold."
1102		)]
1103		///
1104		#[document_returns("The combined monoid value.")]
1105		///
1106		#[document_examples]
1107		///
1108		/// ```
1109		/// use fp_library::brands::VecBrand;
1110		///
1111		/// let result =
1112		/// 	VecBrand::par_fold_map_with_index(|i, x: i32| format!("{i}:{x}"), vec![10, 20, 30]);
1113		/// assert_eq!(result, "0:101:202:30");
1114		/// ```
1115		pub fn par_fold_map_with_index<'a, A: 'a + Send, M: Monoid + Send + 'a>(
1116			f: impl Fn(usize, A) -> M + Send + Sync + 'a,
1117			fa: Vec<A>,
1118		) -> M {
1119			#[cfg(feature = "rayon")]
1120			{
1121				use rayon::prelude::*;
1122				fa.into_par_iter()
1123					.enumerate()
1124					.map(|(i, a)| f(i, a))
1125					.reduce(M::empty, |acc, m| M::append(acc, m))
1126			}
1127			#[cfg(not(feature = "rayon"))]
1128			fa.into_iter()
1129				.enumerate()
1130				.map(|(i, a)| f(i, a))
1131				.fold(M::empty(), |acc, m| M::append(acc, m))
1132		}
1133
1134		/// Maps and filters a vector in parallel with the index, discarding elements where
1135		/// `f` returns `None`.
1136		///
1137		/// When the `rayon` feature is enabled, elements are processed across multiple threads.
1138		/// Otherwise falls back to sequential indexed filter-map.
1139		#[document_signature]
1140		///
1141		#[document_type_parameters(
1142			"The lifetime of the elements.",
1143			"The input element type.",
1144			"The output element type."
1145		)]
1146		///
1147		#[document_parameters(
1148			"The function to apply to each index and element. Must be `Send + Sync`.",
1149			"The vector to filter and map."
1150		)]
1151		///
1152		#[document_returns("A new vector containing the `Some` results of applying `f`.")]
1153		///
1154		#[document_examples]
1155		///
1156		/// ```
1157		/// use fp_library::brands::VecBrand;
1158		///
1159		/// let result = VecBrand::par_filter_map_with_index(
1160		/// 	|i, x: i32| if i < 3 { Some(x * 10) } else { None },
1161		/// 	vec![1, 2, 3, 4, 5],
1162		/// );
1163		/// assert_eq!(result, vec![10, 20, 30]);
1164		/// ```
1165		pub fn par_filter_map_with_index<'a, A: 'a + Send, B: 'a + Send>(
1166			f: impl Fn(usize, A) -> Option<B> + Send + Sync + 'a,
1167			fa: Vec<A>,
1168		) -> Vec<B> {
1169			#[cfg(feature = "rayon")]
1170			{
1171				use rayon::prelude::*;
1172				fa.into_par_iter().enumerate().filter_map(|(i, a)| f(i, a)).collect()
1173			}
1174			#[cfg(not(feature = "rayon"))]
1175			fa.into_iter().enumerate().filter_map(|(i, a)| f(i, a)).collect()
1176		}
1177
1178		/// Filters a vector in parallel with the index, retaining only elements satisfying `f`.
1179		///
1180		/// When the `rayon` feature is enabled, elements are processed across multiple threads.
1181		/// Otherwise falls back to sequential indexed filtering.
1182		#[document_signature]
1183		///
1184		#[document_type_parameters("The lifetime of the elements.", "The element type.")]
1185		///
1186		#[document_parameters(
1187			"The predicate receiving the index and a reference to the element. Must be `Send + Sync`.",
1188			"The vector to filter."
1189		)]
1190		///
1191		#[document_returns("A new vector containing only the elements satisfying `f`.")]
1192		///
1193		#[document_examples]
1194		///
1195		/// ```
1196		/// use fp_library::brands::VecBrand;
1197		///
1198		/// let result =
1199		/// 	VecBrand::par_filter_with_index(|i, x: &i32| i < 3 && x % 2 != 0, vec![1, 2, 3, 4, 5]);
1200		/// assert_eq!(result, vec![1, 3]);
1201		/// ```
1202		pub fn par_filter_with_index<'a, A: 'a + Send>(
1203			f: impl Fn(usize, &A) -> bool + Send + Sync + 'a,
1204			fa: Vec<A>,
1205		) -> Vec<A> {
1206			#[cfg(feature = "rayon")]
1207			{
1208				use rayon::prelude::*;
1209				fa.into_par_iter().enumerate().filter(|(i, a)| f(*i, a)).map(|(_, a)| a).collect()
1210			}
1211			#[cfg(not(feature = "rayon"))]
1212			fa.into_iter().enumerate().filter(|(i, a)| f(*i, a)).map(|(_, a)| a).collect()
1213		}
1214	}
1215
1216	impl ParFunctor for VecBrand {
1217		/// Maps a function over the vector in parallel.
1218		///
1219		/// Delegates to [`VecBrand::par_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 to each element. Must be `Send + Sync`.",
1230			"The vector to map over."
1231		)]
1232		///
1233		#[document_returns("A new vector containing the mapped elements.")]
1234		///
1235		#[document_examples]
1236		///
1237		/// ```
1238		/// use fp_library::{
1239		/// 	brands::VecBrand,
1240		/// 	classes::par_functor::ParFunctor,
1241		/// };
1242		///
1243		/// let result = VecBrand::par_map(|x: i32| x * 2, vec![1, 2, 3]);
1244		/// assert_eq!(result, vec![2, 4, 6]);
1245		/// ```
1246		fn par_map<'a, A: 'a + Send, B: 'a + Send>(
1247			f: impl Fn(A) -> B + Send + Sync + 'a,
1248			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1249		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1250			VecBrand::par_map(f, fa)
1251		}
1252	}
1253
1254	impl ParCompactable for VecBrand {
1255		/// Compacts a vector of options in parallel, discarding `None` values.
1256		///
1257		/// Delegates to [`VecBrand::par_compact`].
1258		#[document_signature]
1259		///
1260		#[document_type_parameters("The lifetime of the elements.", "The element type.")]
1261		///
1262		#[document_parameters("The vector of options.")]
1263		///
1264		#[document_returns("A new vector containing the unwrapped `Some` values.")]
1265		///
1266		#[document_examples]
1267		///
1268		/// ```
1269		/// use fp_library::{
1270		/// 	brands::VecBrand,
1271		/// 	classes::par_compactable::ParCompactable,
1272		/// };
1273		///
1274		/// let result = VecBrand::par_compact(vec![Some(1), None, Some(3)]);
1275		/// assert_eq!(result, vec![1, 3]);
1276		/// ```
1277		fn par_compact<'a, A: 'a + Send>(
1278			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
1279				'a,
1280				Apply!(<OptionBrand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1281			>)
1282		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
1283			VecBrand::par_compact(fa)
1284		}
1285
1286		/// Separates a vector of results into `(errors, oks)` in parallel.
1287		///
1288		/// Delegates to [`VecBrand::par_separate`].
1289		#[document_signature]
1290		///
1291		#[document_type_parameters(
1292			"The lifetime of the elements.",
1293			"The error type.",
1294			"The success type."
1295		)]
1296		///
1297		#[document_parameters("The vector of results.")]
1298		///
1299		#[document_returns(
1300			"A pair `(errs, oks)` where `errs` contains the `Err` values and `oks` the `Ok` values."
1301		)]
1302		///
1303		#[document_examples]
1304		///
1305		/// ```
1306		/// use fp_library::{
1307		/// 	brands::VecBrand,
1308		/// 	classes::par_compactable::ParCompactable,
1309		/// };
1310		///
1311		/// let v: Vec<Result<i32, &str>> = vec![Ok(1), Err("a"), Ok(3)];
1312		/// let (errs, oks): (Vec<&str>, Vec<i32>) = VecBrand::par_separate(v);
1313		/// assert_eq!(errs, vec!["a"]);
1314		/// assert_eq!(oks, vec![1, 3]);
1315		/// ```
1316		fn par_separate<'a, E: 'a + Send, O: 'a + Send>(
1317			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>)
1318		) -> (
1319			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
1320			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
1321		) {
1322			VecBrand::par_separate(fa)
1323		}
1324	}
1325
1326	impl ParFilterable for VecBrand {
1327		/// Maps and filters a vector in parallel, discarding elements where `f` returns `None`.
1328		///
1329		/// Single-pass implementation using rayon's `filter_map`. Delegates to
1330		/// [`VecBrand::par_filter_map`].
1331		#[document_signature]
1332		///
1333		#[document_type_parameters(
1334			"The lifetime of the elements.",
1335			"The input element type.",
1336			"The output element type."
1337		)]
1338		///
1339		#[document_parameters(
1340			"The function to apply. Must be `Send + Sync`.",
1341			"The vector to filter and map."
1342		)]
1343		///
1344		#[document_returns("A new vector containing the `Some` results of applying `f`.")]
1345		///
1346		#[document_examples]
1347		///
1348		/// ```
1349		/// use fp_library::{
1350		/// 	brands::VecBrand,
1351		/// 	classes::par_filterable::ParFilterable,
1352		/// };
1353		///
1354		/// let result = VecBrand::par_filter_map(
1355		/// 	|x: i32| if x % 2 == 0 { Some(x * 10) } else { None },
1356		/// 	vec![1, 2, 3, 4, 5],
1357		/// );
1358		/// assert_eq!(result, vec![20, 40]);
1359		/// ```
1360		fn par_filter_map<'a, A: 'a + Send, B: 'a + Send>(
1361			f: impl Fn(A) -> Option<B> + Send + Sync + 'a,
1362			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1363		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1364			VecBrand::par_filter_map(f, fa)
1365		}
1366
1367		/// Filters a vector in parallel, retaining only elements satisfying `f`.
1368		///
1369		/// Single-pass implementation using rayon's `filter`. Delegates to
1370		/// [`VecBrand::par_filter`].
1371		#[document_signature]
1372		///
1373		#[document_type_parameters("The lifetime of the elements.", "The element type.")]
1374		///
1375		#[document_parameters("The predicate. Must be `Send + Sync`.", "The vector to filter.")]
1376		///
1377		#[document_returns("A new vector containing only the elements satisfying `f`.")]
1378		///
1379		#[document_examples]
1380		///
1381		/// ```
1382		/// use fp_library::{
1383		/// 	brands::VecBrand,
1384		/// 	classes::par_filterable::ParFilterable,
1385		/// };
1386		///
1387		/// let result = VecBrand::par_filter(|x: &i32| x % 2 == 0, vec![1, 2, 3, 4, 5]);
1388		/// assert_eq!(result, vec![2, 4]);
1389		/// ```
1390		fn par_filter<'a, A: 'a + Send>(
1391			f: impl Fn(&A) -> bool + Send + Sync + 'a,
1392			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1393		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
1394			VecBrand::par_filter(f, fa)
1395		}
1396	}
1397
1398	impl ParFoldable for VecBrand {
1399		/// Maps each element to a [`Monoid`] value and combines them in parallel.
1400		///
1401		/// Delegates to [`VecBrand::par_fold_map`].
1402		#[document_signature]
1403		///
1404		#[document_type_parameters(
1405			"The lifetime of the elements.",
1406			"The element type.",
1407			"The monoid type."
1408		)]
1409		///
1410		#[document_parameters(
1411			"The function mapping each element to a monoid value. Must be `Send + Sync`.",
1412			"The vector to fold."
1413		)]
1414		///
1415		#[document_returns("The combined monoid value.")]
1416		///
1417		#[document_examples]
1418		///
1419		/// ```
1420		/// use fp_library::{
1421		/// 	brands::VecBrand,
1422		/// 	classes::par_foldable::ParFoldable,
1423		/// };
1424		///
1425		/// let result = VecBrand::par_fold_map(|x: i32| x.to_string(), vec![1, 2, 3]);
1426		/// assert_eq!(result, "123");
1427		/// ```
1428		fn par_fold_map<'a, A: 'a + Send, M: Monoid + Send + 'a>(
1429			f: impl Fn(A) -> M + Send + Sync + 'a,
1430			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1431		) -> M {
1432			VecBrand::par_fold_map(f, fa)
1433		}
1434	}
1435
1436	impl ParFunctorWithIndex for VecBrand {
1437		/// Maps a function over the vector in parallel, providing each element's index.
1438		///
1439		/// Delegates to [`VecBrand::par_map_with_index`].
1440		#[document_signature]
1441		///
1442		#[document_type_parameters(
1443			"The lifetime of the elements.",
1444			"The input element type.",
1445			"The output element type."
1446		)]
1447		///
1448		#[document_parameters(
1449			"The function to apply to each index and element. Must be `Send + Sync`.",
1450			"The vector to map over."
1451		)]
1452		///
1453		#[document_returns("A new vector containing the mapped elements.")]
1454		///
1455		#[document_examples]
1456		///
1457		/// ```
1458		/// use fp_library::{
1459		/// 	brands::VecBrand,
1460		/// 	classes::par_functor_with_index::ParFunctorWithIndex,
1461		/// };
1462		///
1463		/// let result = VecBrand::par_map_with_index(|i, x: i32| x + i as i32, vec![10, 20, 30]);
1464		/// assert_eq!(result, vec![10, 21, 32]);
1465		/// ```
1466		fn par_map_with_index<'a, A: 'a + Send, B: 'a + Send>(
1467			f: impl Fn(usize, A) -> B + Send + Sync + 'a,
1468			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1469		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
1470		where
1471			usize: Send + Sync + Copy + 'a, {
1472			VecBrand::par_map_with_index(f, fa)
1473		}
1474	}
1475
1476	impl ParFoldableWithIndex for VecBrand {
1477		/// Maps each element and its index to a [`Monoid`] value and combines them in parallel.
1478		///
1479		/// Delegates to [`VecBrand::par_fold_map_with_index`].
1480		#[document_signature]
1481		///
1482		#[document_type_parameters(
1483			"The lifetime of the elements.",
1484			"The element type.",
1485			"The monoid type."
1486		)]
1487		///
1488		#[document_parameters(
1489			"The function mapping each index and element to a monoid value. Must be `Send + Sync`.",
1490			"The vector to fold."
1491		)]
1492		///
1493		#[document_returns("The combined monoid value.")]
1494		///
1495		#[document_examples]
1496		///
1497		/// ```
1498		/// use fp_library::{
1499		/// 	brands::VecBrand,
1500		/// 	classes::par_foldable_with_index::ParFoldableWithIndex,
1501		/// };
1502		///
1503		/// let result =
1504		/// 	VecBrand::par_fold_map_with_index(|i, x: i32| format!("{i}:{x}"), vec![10, 20, 30]);
1505		/// assert_eq!(result, "0:101:202:30");
1506		/// ```
1507		fn par_fold_map_with_index<'a, A: 'a + Send, M: Monoid + Send + 'a>(
1508			f: impl Fn(usize, A) -> M + Send + Sync + 'a,
1509			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1510		) -> M
1511		where
1512			usize: Send + Sync + Copy + 'a, {
1513			VecBrand::par_fold_map_with_index(f, fa)
1514		}
1515	}
1516
1517	impl Compactable for VecBrand {
1518		/// Compacts a vector of options.
1519		///
1520		/// This method flattens a vector of options, discarding `None` values.
1521		#[document_signature]
1522		///
1523		#[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
1524		///
1525		#[document_parameters("The vector of options.")]
1526		///
1527		#[document_returns("The flattened vector.")]
1528		///
1529		#[document_examples]
1530		///
1531		/// ```
1532		/// use fp_library::{
1533		/// 	brands::VecBrand,
1534		/// 	functions::*,
1535		/// };
1536		///
1537		/// let x = vec![Some(1), None, Some(2)];
1538		/// let y = explicit::compact::<VecBrand, _, _, _>(x);
1539		/// assert_eq!(y, vec![1, 2]);
1540		/// ```
1541		fn compact<'a, A: 'a>(
1542			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
1543			'a,
1544			Apply!(<OptionBrand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1545		>)
1546		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
1547			fa.into_iter().flatten().collect()
1548		}
1549
1550		/// Separates a vector of results.
1551		///
1552		/// This method separates a vector of results into a pair of vectors.
1553		#[document_signature]
1554		///
1555		#[document_type_parameters(
1556			"The lifetime of the elements.",
1557			"The type of the error value.",
1558			"The type of the success value."
1559		)]
1560		///
1561		#[document_parameters("The vector of results.")]
1562		///
1563		#[document_returns("A pair of vectors.")]
1564		///
1565		#[document_examples]
1566		///
1567		/// ```
1568		/// use fp_library::{
1569		/// 	brands::*,
1570		/// 	functions::*,
1571		/// };
1572		///
1573		/// let x = vec![Ok(1), Err("error"), Ok(2)];
1574		/// let (errs, oks) = explicit::separate::<VecBrand, _, _, _, _>(x);
1575		/// assert_eq!(oks, vec![1, 2]);
1576		/// assert_eq!(errs, vec!["error"]);
1577		/// ```
1578		fn separate<'a, E: 'a, O: 'a>(
1579			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>)
1580		) -> (
1581			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
1582			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
1583		) {
1584			let mut oks = Vec::new();
1585			let mut errs = Vec::new();
1586			for result in fa {
1587				match result {
1588					Ok(o) => oks.push(o),
1589					Err(e) => errs.push(e),
1590				}
1591			}
1592			(errs, oks)
1593		}
1594	}
1595
1596	impl RefCompactable for VecBrand {
1597		/// Compacts a borrowed vector of options, discarding [`None`] values and cloning [`Some`] values.
1598		///
1599		/// This method iterates over a borrowed vector of options, keeping only the [`Some`] values
1600		/// by cloning them into a new vector.
1601		#[document_signature]
1602		///
1603		#[document_type_parameters(
1604			"The lifetime of the elements.",
1605			"The type of the elements in the [`Option`]. Must be [`Clone`] because elements are extracted from a borrowed container."
1606		)]
1607		///
1608		#[document_parameters("A reference to the vector containing [`Option`] values.")]
1609		///
1610		#[document_returns(
1611			"A new vector containing only the cloned values from the [`Some`] variants."
1612		)]
1613		///
1614		#[document_examples]
1615		///
1616		/// ```
1617		/// use fp_library::{
1618		/// 	brands::VecBrand,
1619		/// 	functions::*,
1620		/// };
1621		///
1622		/// let v = vec![Some(1), None, Some(3)];
1623		/// let result = explicit::compact::<VecBrand, _, _, _>(&v);
1624		/// assert_eq!(result, vec![1, 3]);
1625		/// ```
1626		fn ref_compact<'a, A: 'a + Clone>(
1627			fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<A>>)
1628		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
1629			fa.iter().filter_map(|opt| opt.as_ref().cloned()).collect()
1630		}
1631
1632		/// Separates a borrowed vector of results into two vectors: one containing the cloned [`Err`] values and one containing the cloned [`Ok`] values.
1633		///
1634		/// This method iterates over a borrowed vector of results, cloning each value into the
1635		/// appropriate output vector.
1636		#[document_signature]
1637		///
1638		#[document_type_parameters(
1639			"The lifetime of the elements.",
1640			"The type of the error values. Must be [`Clone`] because elements are extracted from a borrowed container.",
1641			"The type of the success values. Must be [`Clone`] because elements are extracted from a borrowed container."
1642		)]
1643		///
1644		#[document_parameters("A reference to the vector containing [`Result`] values.")]
1645		///
1646		#[document_returns(
1647			"A pair of vectors: the first containing the cloned [`Err`] values, and the second containing the cloned [`Ok`] values."
1648		)]
1649		///
1650		#[document_examples]
1651		///
1652		/// ```
1653		/// use fp_library::{
1654		/// 	brands::VecBrand,
1655		/// 	functions::*,
1656		/// };
1657		///
1658		/// let v: Vec<Result<i32, &str>> = vec![Ok(1), Err("bad"), Ok(3)];
1659		/// let (errs, oks) = explicit::separate::<VecBrand, _, _, _, _>(&v);
1660		/// assert_eq!(oks, vec![1, 3]);
1661		/// assert_eq!(errs, vec!["bad"]);
1662		/// ```
1663		fn ref_separate<'a, E: 'a + Clone, O: 'a + Clone>(
1664			fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>)
1665		) -> (
1666			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
1667			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
1668		) {
1669			let mut errs = Vec::new();
1670			let mut oks = Vec::new();
1671			for result in fa.iter() {
1672				match result {
1673					Ok(o) => oks.push(o.clone()),
1674					Err(e) => errs.push(e.clone()),
1675				}
1676			}
1677			(errs, oks)
1678		}
1679	}
1680
1681	impl Filterable for VecBrand {
1682		/// Partitions a vector based on a function that returns a result.
1683		///
1684		/// This method partitions a vector based on a function that returns a result.
1685		#[document_signature]
1686		///
1687		#[document_type_parameters(
1688			"The lifetime of the elements.",
1689			"The type of the input value.",
1690			"The type of the error value.",
1691			"The type of the success value."
1692		)]
1693		///
1694		#[document_parameters("The function to apply.", "The vector to partition.")]
1695		///
1696		#[document_returns("A pair of vectors.")]
1697		///
1698		#[document_examples]
1699		///
1700		/// ```
1701		/// use fp_library::{
1702		/// 	brands::*,
1703		/// 	functions::*,
1704		/// };
1705		///
1706		/// let x = vec![1, 2, 3, 4];
1707		/// let (errs, oks) = explicit::partition_map::<VecBrand, _, _, _, _, _>(
1708		/// 	|a| if a % 2 == 0 { Ok(a) } else { Err(a) },
1709		/// 	x,
1710		/// );
1711		/// assert_eq!(oks, vec![2, 4]);
1712		/// assert_eq!(errs, vec![1, 3]);
1713		/// ```
1714		fn partition_map<'a, A: 'a, E: 'a, O: 'a>(
1715			func: impl Fn(A) -> Result<O, E> + 'a,
1716			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1717		) -> (
1718			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
1719			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
1720		) {
1721			let mut oks = Vec::new();
1722			let mut errs = Vec::new();
1723			for a in fa {
1724				match func(a) {
1725					Ok(o) => oks.push(o),
1726					Err(e) => errs.push(e),
1727				}
1728			}
1729			(errs, oks)
1730		}
1731
1732		/// Partitions a vector based on a predicate.
1733		///
1734		/// This method partitions a vector based on a predicate.
1735		#[document_signature]
1736		///
1737		#[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
1738		///
1739		#[document_parameters("The predicate.", "The vector to partition.")]
1740		///
1741		#[document_returns("A pair of vectors.")]
1742		///
1743		#[document_examples]
1744		///
1745		/// ```
1746		/// use fp_library::{
1747		/// 	brands::*,
1748		/// 	functions::*,
1749		/// };
1750		///
1751		/// let x = vec![1, 2, 3, 4];
1752		/// let (not_satisfied, satisfied) = explicit::partition::<VecBrand, _, _, _>(|a| a % 2 == 0, x);
1753		/// assert_eq!(satisfied, vec![2, 4]);
1754		/// assert_eq!(not_satisfied, vec![1, 3]);
1755		/// ```
1756		fn partition<'a, A: 'a + Clone>(
1757			func: impl Fn(A) -> bool + 'a,
1758			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1759		) -> (
1760			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1761			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1762		) {
1763			let (satisfied, not_satisfied): (Vec<A>, Vec<A>) =
1764				fa.into_iter().partition(|a| func(a.clone()));
1765			(not_satisfied, satisfied)
1766		}
1767
1768		/// Maps a function over a vector and filters out `None` results.
1769		///
1770		/// This method maps a function over a vector and filters out `None` results.
1771		#[document_signature]
1772		///
1773		#[document_type_parameters(
1774			"The lifetime of the elements.",
1775			"The type of the input value.",
1776			"The type of the result of applying the function."
1777		)]
1778		///
1779		#[document_parameters("The function to apply.", "The vector to filter and map.")]
1780		///
1781		#[document_returns("The filtered and mapped vector.")]
1782		///
1783		#[document_examples]
1784		///
1785		/// ```
1786		/// use fp_library::{
1787		/// 	brands::VecBrand,
1788		/// 	functions::*,
1789		/// };
1790		///
1791		/// let x = vec![1, 2, 3, 4];
1792		/// let y = explicit::filter_map::<VecBrand, _, _, _, _>(
1793		/// 	|a| if a % 2 == 0 { Some(a * 2) } else { None },
1794		/// 	x,
1795		/// );
1796		/// assert_eq!(y, vec![4, 8]);
1797		/// ```
1798		fn filter_map<'a, A: 'a, B: 'a>(
1799			func: impl Fn(A) -> Option<B> + 'a,
1800			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1801		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1802			fa.into_iter().filter_map(func).collect()
1803		}
1804
1805		/// Filters a vector based on a predicate.
1806		///
1807		/// This method filters a vector based on a predicate.
1808		#[document_signature]
1809		///
1810		#[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
1811		///
1812		#[document_parameters("The predicate.", "The vector to filter.")]
1813		///
1814		#[document_returns("The filtered vector.")]
1815		///
1816		#[document_examples]
1817		///
1818		/// ```
1819		/// use fp_library::{
1820		/// 	brands::VecBrand,
1821		/// 	functions::*,
1822		/// };
1823		///
1824		/// let x = vec![1, 2, 3, 4];
1825		/// let y = explicit::filter::<VecBrand, _, _, _>(|a| a % 2 == 0, x);
1826		/// assert_eq!(y, vec![2, 4]);
1827		/// ```
1828		fn filter<'a, A: 'a + Clone>(
1829			func: impl Fn(A) -> bool + 'a,
1830			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1831		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
1832			fa.into_iter().filter(|a| func(a.clone())).collect()
1833		}
1834	}
1835
1836	impl FilterableWithIndex for VecBrand {
1837		/// Partitions a vector based on a function that receives the index and returns a [`Result`].
1838		#[document_signature]
1839		///
1840		#[document_type_parameters(
1841			"The lifetime of the elements.",
1842			"The type of the input value.",
1843			"The type of the error value.",
1844			"The type of the success value."
1845		)]
1846		///
1847		#[document_parameters(
1848			"The function to apply to each element and its index.",
1849			"The vector to partition."
1850		)]
1851		///
1852		#[document_returns("A pair of vectors.")]
1853		///
1854		#[document_examples]
1855		///
1856		/// ```
1857		/// use fp_library::{
1858		/// 	brands::*,
1859		/// 	functions::*,
1860		/// };
1861		///
1862		/// let xs = vec![1, 2, 3, 4];
1863		/// let (errs, oks) = explicit::partition_map_with_index::<VecBrand, _, _, _, _, _>(
1864		/// 	|i, a: i32| if i < 2 { Ok(a) } else { Err(a) },
1865		/// 	xs,
1866		/// );
1867		/// assert_eq!(oks, vec![1, 2]);
1868		/// assert_eq!(errs, vec![3, 4]);
1869		/// ```
1870		fn partition_map_with_index<'a, A: 'a, E: 'a, O: 'a>(
1871			func: impl Fn(usize, A) -> Result<O, E> + 'a,
1872			fa: Vec<A>,
1873		) -> (Vec<E>, Vec<O>) {
1874			let mut oks = Vec::new();
1875			let mut errs = Vec::new();
1876			for (i, a) in fa.into_iter().enumerate() {
1877				match func(i, a) {
1878					Ok(o) => oks.push(o),
1879					Err(e) => errs.push(e),
1880				}
1881			}
1882			(errs, oks)
1883		}
1884
1885		/// Partitions a vector based on a predicate that receives the index.
1886		#[document_signature]
1887		///
1888		#[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
1889		///
1890		#[document_parameters(
1891			"The predicate receiving the index and element.",
1892			"The vector to partition."
1893		)]
1894		///
1895		#[document_returns("A pair of vectors.")]
1896		///
1897		#[document_examples]
1898		///
1899		/// ```
1900		/// use fp_library::{
1901		/// 	brands::*,
1902		/// 	functions::*,
1903		/// };
1904		///
1905		/// let xs = vec![1, 2, 3, 4];
1906		/// let (not_satisfied, satisfied) =
1907		/// 	explicit::partition_with_index::<VecBrand, _, _, _>(|i, _a: i32| i < 2, xs);
1908		/// assert_eq!(satisfied, vec![1, 2]);
1909		/// assert_eq!(not_satisfied, vec![3, 4]);
1910		/// ```
1911		fn partition_with_index<'a, A: 'a + Clone>(
1912			func: impl Fn(usize, A) -> bool + 'a,
1913			fa: Vec<A>,
1914		) -> (Vec<A>, Vec<A>) {
1915			let mut satisfied = Vec::new();
1916			let mut not_satisfied = Vec::new();
1917			for (i, a) in fa.into_iter().enumerate() {
1918				if func(i, a.clone()) {
1919					satisfied.push(a);
1920				} else {
1921					not_satisfied.push(a);
1922				}
1923			}
1924			(not_satisfied, satisfied)
1925		}
1926
1927		/// Maps a function over a vector with the index and filters out [`None`] results.
1928		#[document_signature]
1929		///
1930		#[document_type_parameters(
1931			"The lifetime of the elements.",
1932			"The type of the input value.",
1933			"The type of the result of applying the function."
1934		)]
1935		///
1936		#[document_parameters(
1937			"The function to apply to each element and its index.",
1938			"The vector to filter and map."
1939		)]
1940		///
1941		#[document_returns("The filtered and mapped vector.")]
1942		///
1943		#[document_examples]
1944		///
1945		/// ```
1946		/// use fp_library::{
1947		/// 	brands::VecBrand,
1948		/// 	functions::*,
1949		/// };
1950		///
1951		/// let xs = vec![1, 2, 3, 4];
1952		/// let result = explicit::filter_map_with_index::<VecBrand, _, _, _, _>(
1953		/// 	|i, a: i32| if i % 2 == 0 { Some(a * 2) } else { None },
1954		/// 	xs,
1955		/// );
1956		/// assert_eq!(result, vec![2, 6]);
1957		/// ```
1958		fn filter_map_with_index<'a, A: 'a, B: 'a>(
1959			func: impl Fn(usize, A) -> Option<B> + 'a,
1960			fa: Vec<A>,
1961		) -> Vec<B> {
1962			fa.into_iter().enumerate().filter_map(|(i, a)| func(i, a)).collect()
1963		}
1964
1965		/// Filters a vector based on a predicate that receives the index.
1966		#[document_signature]
1967		///
1968		#[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
1969		///
1970		#[document_parameters(
1971			"The predicate receiving the index and element.",
1972			"The vector to filter."
1973		)]
1974		///
1975		#[document_returns("The filtered vector.")]
1976		///
1977		#[document_examples]
1978		///
1979		/// ```
1980		/// use fp_library::{
1981		/// 	brands::VecBrand,
1982		/// 	functions::*,
1983		/// };
1984		///
1985		/// let xs = vec![1, 2, 3, 4];
1986		/// let result = explicit::filter_with_index::<VecBrand, _, _, _>(|i, _a: i32| i < 2, xs);
1987		/// assert_eq!(result, vec![1, 2]);
1988		/// ```
1989		fn filter_with_index<'a, A: 'a + Clone>(
1990			func: impl Fn(usize, A) -> bool + 'a,
1991			fa: Vec<A>,
1992		) -> Vec<A> {
1993			fa.into_iter()
1994				.enumerate()
1995				.filter(|(i, a)| func(*i, a.clone()))
1996				.map(|(_, a)| a)
1997				.collect()
1998		}
1999	}
2000
2001	impl ParFilterableWithIndex for VecBrand {
2002		/// Maps and filters a vector in parallel with the index, discarding elements where
2003		/// `f` returns `None`.
2004		///
2005		/// Single-pass implementation using rayon's `enumerate` + `filter_map`. Delegates to
2006		/// [`VecBrand::par_filter_map_with_index`].
2007		#[document_signature]
2008		///
2009		#[document_type_parameters(
2010			"The lifetime of the elements.",
2011			"The input element type.",
2012			"The output element type."
2013		)]
2014		///
2015		#[document_parameters(
2016			"The function to apply to each index and element. Must be `Send + Sync`.",
2017			"The vector to filter and map."
2018		)]
2019		///
2020		#[document_returns("A new vector containing the `Some` results of applying `f`.")]
2021		///
2022		#[document_examples]
2023		///
2024		/// ```
2025		/// use fp_library::{
2026		/// 	brands::VecBrand,
2027		/// 	classes::par_filterable_with_index::ParFilterableWithIndex,
2028		/// };
2029		///
2030		/// let result = VecBrand::par_filter_map_with_index(
2031		/// 	|i, x: i32| if i < 3 { Some(x * 10) } else { None },
2032		/// 	vec![1, 2, 3, 4, 5],
2033		/// );
2034		/// assert_eq!(result, vec![10, 20, 30]);
2035		/// ```
2036		fn par_filter_map_with_index<'a, A: 'a + Send, B: 'a + Send>(
2037			f: impl Fn(usize, A) -> Option<B> + Send + Sync + 'a,
2038			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
2039		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
2040		where
2041			usize: Send + Sync + Copy + 'a, {
2042			VecBrand::par_filter_map_with_index(f, fa)
2043		}
2044
2045		/// Filters a vector in parallel with the index, retaining only elements satisfying `f`.
2046		///
2047		/// Single-pass implementation using rayon's `enumerate` + `filter`. Delegates to
2048		/// [`VecBrand::par_filter_with_index`].
2049		#[document_signature]
2050		///
2051		#[document_type_parameters("The lifetime of the elements.", "The element type.")]
2052		///
2053		#[document_parameters(
2054			"The predicate receiving the index and a reference to the element. Must be `Send + Sync`.",
2055			"The vector to filter."
2056		)]
2057		///
2058		#[document_returns("A new vector containing only the elements satisfying `f`.")]
2059		///
2060		#[document_examples]
2061		///
2062		/// ```
2063		/// use fp_library::{
2064		/// 	brands::VecBrand,
2065		/// 	classes::par_filterable_with_index::ParFilterableWithIndex,
2066		/// };
2067		///
2068		/// let result =
2069		/// 	VecBrand::par_filter_with_index(|i, x: &i32| i < 3 && x % 2 != 0, vec![1, 2, 3, 4, 5]);
2070		/// assert_eq!(result, vec![1, 3]);
2071		/// ```
2072		fn par_filter_with_index<'a, A: 'a + Send>(
2073			f: impl Fn(usize, &A) -> bool + Send + Sync + 'a,
2074			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
2075		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>)
2076		where
2077			usize: Send + Sync + Copy + 'a, {
2078			VecBrand::par_filter_with_index(f, fa)
2079		}
2080	}
2081
2082	impl Witherable for VecBrand {
2083		/// Partitions a vector based on a function that returns a result in an applicative context.
2084		///
2085		/// This method partitions a vector based on a function that returns a result in an applicative context.
2086		#[document_signature]
2087		///
2088		#[document_type_parameters(
2089			"The lifetime of the elements.",
2090			"The applicative context.",
2091			"The type of the input value.",
2092			"The type of the error value.",
2093			"The type of the success value."
2094		)]
2095		///
2096		#[document_parameters("The function to apply.", "The vector to partition.")]
2097		///
2098		#[document_returns("The partitioned vector wrapped in the applicative context.")]
2099		///
2100		#[document_examples]
2101		///
2102		/// ```
2103		/// use fp_library::{
2104		/// 	brands::*,
2105		/// 	functions::*,
2106		/// };
2107		///
2108		/// let x = vec![1, 2, 3, 4];
2109		/// let y = explicit::wilt::<RcFnBrand, VecBrand, OptionBrand, _, _, _, _, _>(
2110		/// 	|a| Some(if a % 2 == 0 { Ok(a) } else { Err(a) }),
2111		/// 	x,
2112		/// );
2113		/// assert_eq!(y, Some((vec![1, 3], vec![2, 4])));
2114		/// ```
2115		fn wilt<'a, M: Applicative, A: 'a + Clone, E: 'a + Clone, O: 'a + Clone>(
2116			func: impl Fn(A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>)
2117			+ 'a,
2118			ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
2119		) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
2120		'a,
2121		(
2122			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
2123			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
2124		),
2125	>)
2126		where
2127			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>): Clone,
2128			Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>): Clone, {
2129			ta.into_iter().fold(M::pure((Vec::new(), Vec::new())), |acc, x| {
2130				M::lift2(
2131					|mut pair, res| {
2132						match res {
2133							Ok(o) => pair.1.push(o),
2134							Err(e) => pair.0.push(e),
2135						}
2136						pair
2137					},
2138					acc,
2139					func(x),
2140				)
2141			})
2142		}
2143
2144		/// Maps a function over a vector and filters out `None` results in an applicative context.
2145		///
2146		/// This method maps a function over a vector and filters out `None` results in an applicative context.
2147		#[document_signature]
2148		///
2149		#[document_type_parameters(
2150			"The lifetime of the values.",
2151			"The applicative context.",
2152			"The type of the elements in the input structure.",
2153			"The type of the result of applying the function."
2154		)]
2155		///
2156		#[document_parameters(
2157			"The function to apply to each element, returning an `Option` in an applicative context.",
2158			"The vector to filter and map."
2159		)]
2160		///
2161		#[document_returns("The filtered and mapped vector wrapped in the applicative context.")]
2162		#[document_examples]
2163		///
2164		/// ```
2165		/// use fp_library::{
2166		/// 	brands::*,
2167		/// 	functions::*,
2168		/// };
2169		///
2170		/// let x = vec![1, 2, 3, 4];
2171		/// let y = explicit::wither::<RcFnBrand, VecBrand, OptionBrand, _, _, _, _>(
2172		/// 	|a| Some(if a % 2 == 0 { Some(a * 2) } else { None }),
2173		/// 	x,
2174		/// );
2175		/// assert_eq!(y, Some(vec![4, 8]));
2176		/// ```
2177		fn wither<'a, M: Applicative, A: 'a + Clone, B: 'a + Clone>(
2178			func: impl Fn(A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>) + 'a,
2179			ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
2180		) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
2181		'a,
2182		Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
2183	>)
2184		where
2185			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>): Clone,
2186			Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>): Clone, {
2187			ta.into_iter().fold(M::pure(Vec::new()), |acc, x| {
2188				M::lift2(
2189					|mut v, opt_b| {
2190						if let Some(b) = opt_b {
2191							v.push(b);
2192						}
2193						v
2194					},
2195					acc,
2196					func(x),
2197				)
2198			})
2199		}
2200	}
2201
2202	/// Cooperative extension for [`Vec`], ported from PureScript's `Extend Array` instance.
2203	///
2204	/// `extend(f, vec)` produces a new vector where each element at index `i` is
2205	/// `f` applied to the suffix `vec[i..]`. This is the dual of [`Semimonad::bind`]:
2206	/// where `bind` feeds each element into a function that produces a new context,
2207	/// `extend` feeds each suffix (context) into a function that produces a single value.
2208	///
2209	/// Requires `A: Clone` because suffixes are materialized as owned vectors.
2210	impl Extend for VecBrand {
2211		/// Extends a local context-dependent computation to a global computation over
2212		/// [`Vec`].
2213		///
2214		/// Applies `f` to every suffix of the input vector. For a vector
2215		/// `[a, b, c]`, the result is `[f([a, b, c]), f([b, c]), f([c])]`.
2216		#[document_signature]
2217		///
2218		#[document_type_parameters(
2219			"The lifetime of the values.",
2220			"The type of the elements in the vector.",
2221			"The result type of the extension function."
2222		)]
2223		///
2224		#[document_parameters(
2225			"The function that consumes a suffix vector and produces a value.",
2226			"The vector to extend over."
2227		)]
2228		///
2229		#[document_returns(
2230			"A new vector containing the results of applying the function to each suffix."
2231		)]
2232		///
2233		#[document_examples]
2234		///
2235		/// ```
2236		/// use fp_library::{
2237		/// 	brands::*,
2238		/// 	functions::*,
2239		/// };
2240		///
2241		/// let result = extend::<VecBrand, _, _>(|v: Vec<i32>| v.iter().sum::<i32>(), vec![1, 2, 3]);
2242		/// assert_eq!(result, vec![6, 5, 3]);
2243		/// ```
2244		fn extend<'a, A: 'a + Clone, B: 'a>(
2245			f: impl Fn(Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>)) -> B + 'a,
2246			wa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
2247		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
2248			(0 .. wa.len()).map(|i| f(wa.get(i ..).unwrap_or_default().to_vec())).collect()
2249		}
2250	}
2251
2252	impl MonadRec for VecBrand {
2253		/// Performs tail-recursive monadic computation over [`Vec`].
2254		///
2255		/// Since `Vec` represents nondeterminism, this performs a breadth-first
2256		/// expansion: each iteration maps all current `Loop` states through the step
2257		/// function, collecting `Done` results as they appear. The computation
2258		/// terminates when no `Loop` values remain.
2259		#[document_signature]
2260		///
2261		#[document_type_parameters(
2262			"The lifetime of the computation.",
2263			"The type of the initial value and loop state.",
2264			"The type of the result."
2265		)]
2266		///
2267		#[document_parameters("The step function.", "The initial value.")]
2268		///
2269		#[document_returns("A vector of all completed results.")]
2270		///
2271		#[document_examples]
2272		///
2273		/// ```
2274		/// use {
2275		/// 	core::ops::ControlFlow,
2276		/// 	fp_library::{
2277		/// 		brands::*,
2278		/// 		functions::*,
2279		/// 		types::*,
2280		/// 	},
2281		/// };
2282		///
2283		/// // Branch into two paths, each running until done
2284		/// let result = tail_rec_m::<VecBrand, _, _>(
2285		/// 	|n| {
2286		/// 		if n < 3 {
2287		/// 			vec![ControlFlow::Continue(n + 1), ControlFlow::Break(n * 10)]
2288		/// 		} else {
2289		/// 			vec![ControlFlow::Break(n * 10)]
2290		/// 		}
2291		/// 	},
2292		/// 	0,
2293		/// );
2294		/// // Starting from 0: branches at 0,1,2; done at 3
2295		/// assert_eq!(result, vec![0, 10, 20, 30]);
2296		/// ```
2297		fn tail_rec_m<'a, A: 'a, B: 'a>(
2298			func: impl Fn(
2299				A,
2300			)
2301				-> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, ControlFlow<B, A>>)
2302			+ 'a,
2303			initial: A,
2304		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
2305			let mut done: Vec<B> = Vec::new();
2306			let mut pending: Vec<A> = vec![initial];
2307			while !pending.is_empty() {
2308				let mut next_pending: Vec<A> = Vec::new();
2309				for a in pending {
2310					for step in func(a) {
2311						match step {
2312							ControlFlow::Continue(next) => next_pending.push(next),
2313							ControlFlow::Break(b) => done.push(b),
2314						}
2315					}
2316				}
2317				pending = next_pending;
2318			}
2319			done
2320		}
2321	}
2322
2323	// -- By-reference trait implementations --
2324
2325	impl RefFunctor for VecBrand {
2326		/// Maps a function over the vector by reference.
2327		#[document_signature]
2328		///
2329		#[document_type_parameters(
2330			"The lifetime of the elements.",
2331			"The type of the elements in the vector.",
2332			"The type of the elements in the resulting vector."
2333		)]
2334		///
2335		#[document_parameters(
2336			"The function to apply to each element reference.",
2337			"The vector to map over."
2338		)]
2339		///
2340		#[document_returns("A new vector containing the results.")]
2341		///
2342		#[document_examples]
2343		///
2344		/// ```
2345		/// use fp_library::{
2346		/// 	brands::*,
2347		/// 	functions::*,
2348		/// };
2349		///
2350		/// assert_eq!(
2351		/// 	explicit::map::<VecBrand, _, _, _, _>(|x: &i32| *x * 2, &vec![1, 2, 3]),
2352		/// 	vec![2, 4, 6]
2353		/// );
2354		/// ```
2355		fn ref_map<'a, A: 'a, B: 'a>(
2356			func: impl Fn(&A) -> B + 'a,
2357			fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
2358		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
2359			fa.iter().map(func).collect()
2360		}
2361	}
2362
2363	impl RefFoldable for VecBrand {
2364		/// Folds the vector by reference using a monoid.
2365		#[document_signature]
2366		///
2367		#[document_type_parameters(
2368			"The lifetime of the elements.",
2369			"The brand of the cloneable function wrapper.",
2370			"The type of the elements.",
2371			"The monoid type."
2372		)]
2373		///
2374		#[document_parameters(
2375			"The function to map each element reference to a monoid.",
2376			"The vector to fold."
2377		)]
2378		///
2379		#[document_returns("The combined monoid value.")]
2380		///
2381		#[document_examples]
2382		///
2383		/// ```
2384		/// use fp_library::{
2385		/// 	brands::*,
2386		/// 	functions::*,
2387		/// };
2388		///
2389		/// let v = vec![1, 2, 3];
2390		/// let result = explicit::fold_map::<RcFnBrand, VecBrand, _, _, _, _>(|x: &i32| x.to_string(), &v);
2391		/// assert_eq!(result, "123");
2392		/// ```
2393		fn ref_fold_map<'a, FnBrand, A: 'a + Clone, M>(
2394			func: impl Fn(&A) -> M + 'a,
2395			fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
2396		) -> M
2397		where
2398			FnBrand: LiftFn + 'a,
2399			M: Monoid + 'a, {
2400			fa.iter().fold(Monoid::empty(), |acc, a| Semigroup::append(acc, func(a)))
2401		}
2402	}
2403
2404	impl RefFilterable for VecBrand {
2405		/// Filters and maps the vector by reference.
2406		#[document_signature]
2407		///
2408		#[document_type_parameters(
2409			"The lifetime of the elements.",
2410			"The type of the input elements.",
2411			"The type of the output elements."
2412		)]
2413		///
2414		#[document_parameters("The filter-map function.", "The vector to filter.")]
2415		///
2416		#[document_returns("The filtered vector.")]
2417		///
2418		#[document_examples]
2419		///
2420		/// ```
2421		/// use fp_library::{
2422		/// 	brands::*,
2423		/// 	functions::*,
2424		/// };
2425		///
2426		/// let v = vec![1, 2, 3, 4, 5];
2427		/// let result = explicit::filter_map::<VecBrand, _, _, _, _>(
2428		/// 	|x: &i32| if *x > 3 { Some(*x) } else { None },
2429		/// 	&v,
2430		/// );
2431		/// assert_eq!(result, vec![4, 5]);
2432		/// ```
2433		fn ref_filter_map<'a, A: 'a, B: 'a>(
2434			func: impl Fn(&A) -> Option<B> + 'a,
2435			fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
2436		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
2437			fa.iter().filter_map(func).collect()
2438		}
2439	}
2440
2441	impl RefTraversable for VecBrand {
2442		/// Traverses the vector by reference.
2443		#[document_signature]
2444		///
2445		#[document_type_parameters(
2446			"The lifetime of the elements.",
2447			"The brand of the cloneable function wrapper.",
2448			"The type of the input elements.",
2449			"The type of the output elements.",
2450			"The applicative functor brand."
2451		)]
2452		///
2453		#[document_parameters(
2454			"The function to apply to each element reference.",
2455			"The vector to traverse."
2456		)]
2457		///
2458		#[document_returns("The combined result in the applicative context.")]
2459		///
2460		#[document_examples]
2461		///
2462		/// ```
2463		/// use fp_library::{
2464		/// 	brands::*,
2465		/// 	functions::*,
2466		/// };
2467		///
2468		/// let v = vec![1, 2, 3];
2469		/// let result: Option<Vec<String>> =
2470		/// 	ref_traverse::<VecBrand, RcFnBrand, _, _, OptionBrand>(|x: &i32| Some(x.to_string()), &v);
2471		/// assert_eq!(result, Some(vec!["1".to_string(), "2".to_string(), "3".to_string()]));
2472		/// ```
2473		fn ref_traverse<'a, FnBrand, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
2474			func: impl Fn(&A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
2475			ta: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
2476		) -> 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>)>)
2477		where
2478			FnBrand: LiftFn + 'a,
2479			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
2480			Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
2481			let len = ta.len();
2482			ta.iter().fold(
2483				F::pure::<Vec<B>>(Vec::with_capacity(len)),
2484				|acc: Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Vec<B>>), a| {
2485					F::lift2(
2486						|mut v: Vec<B>, b: B| {
2487							v.push(b);
2488							v
2489						},
2490						acc,
2491						func(a),
2492					)
2493				},
2494			)
2495		}
2496	}
2497
2498	impl RefWitherable for VecBrand {}
2499
2500	impl RefFunctorWithIndex for VecBrand {
2501		/// Maps a function with index over the vector by reference.
2502		#[document_signature]
2503		///
2504		#[document_type_parameters(
2505			"The lifetime of the elements.",
2506			"The type of the input elements.",
2507			"The type of the output elements."
2508		)]
2509		///
2510		#[document_parameters("The function to apply.", "The vector to map over.")]
2511		///
2512		#[document_returns("The mapped vector.")]
2513		///
2514		#[document_examples]
2515		///
2516		/// ```
2517		/// use fp_library::{
2518		/// 	brands::*,
2519		/// 	functions::*,
2520		/// };
2521		///
2522		/// let v = vec![10, 20, 30];
2523		/// let result =
2524		/// 	explicit::map_with_index::<VecBrand, _, _, _, _>(|i, x: &i32| format!("{}:{}", i, x), &v);
2525		/// assert_eq!(result, vec!["0:10", "1:20", "2:30"]);
2526		/// ```
2527		fn ref_map_with_index<'a, A: 'a, B: 'a>(
2528			func: impl Fn(usize, &A) -> B + 'a,
2529			fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
2530		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
2531			fa.iter().enumerate().map(|(i, a)| func(i, a)).collect()
2532		}
2533	}
2534
2535	impl RefFoldableWithIndex for VecBrand {
2536		/// Folds the vector by reference with index using a monoid.
2537		#[document_signature]
2538		///
2539		#[document_type_parameters(
2540			"The lifetime of the elements.",
2541			"The brand of the cloneable function to use.",
2542			"The type of the elements.",
2543			"The monoid type."
2544		)]
2545		///
2546		#[document_parameters(
2547			"The function to map each (index, element reference) pair.",
2548			"The vector to fold."
2549		)]
2550		///
2551		#[document_returns("The combined monoid value.")]
2552		///
2553		#[document_examples]
2554		///
2555		/// ```
2556		/// use fp_library::{
2557		/// 	brands::*,
2558		/// 	functions::*,
2559		/// };
2560		///
2561		/// let v = vec![10, 20, 30];
2562		/// let result = explicit::fold_map_with_index::<RcFnBrand, VecBrand, _, _, _, _>(
2563		/// 	|i, x: &i32| format!("{}:{}", i, x),
2564		/// 	&v,
2565		/// );
2566		/// assert_eq!(result, "0:101:202:30");
2567		/// ```
2568		fn ref_fold_map_with_index<'a, FnBrand, A: 'a + Clone, R: Monoid + 'a>(
2569			func: impl Fn(usize, &A) -> R + 'a,
2570			fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
2571		) -> R
2572		where
2573			FnBrand: LiftFn + 'a, {
2574			fa.iter()
2575				.enumerate()
2576				.fold(Monoid::empty(), |acc, (i, a)| Semigroup::append(acc, func(i, a)))
2577		}
2578	}
2579
2580	impl RefFilterableWithIndex for VecBrand {
2581		/// Filters and maps the vector by reference with index.
2582		#[document_signature]
2583		///
2584		#[document_type_parameters(
2585			"The lifetime of the elements.",
2586			"The type of the input elements.",
2587			"The type of the output elements."
2588		)]
2589		///
2590		#[document_parameters("The filter-map function.", "The vector to filter.")]
2591		///
2592		#[document_returns("The filtered vector.")]
2593		///
2594		#[document_examples]
2595		///
2596		/// ```
2597		/// use fp_library::{
2598		/// 	brands::*,
2599		/// 	functions::*,
2600		/// };
2601		///
2602		/// let v = vec![10, 20, 30, 40, 50];
2603		/// let result = explicit::filter_map_with_index::<VecBrand, _, _, _, _>(
2604		/// 	|i, x: &i32| if i >= 2 { Some(*x) } else { None },
2605		/// 	&v,
2606		/// );
2607		/// assert_eq!(result, vec![30, 40, 50]);
2608		/// ```
2609		fn ref_filter_map_with_index<'a, A: 'a, B: 'a>(
2610			func: impl Fn(usize, &A) -> Option<B> + 'a,
2611			fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
2612		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
2613			fa.iter().enumerate().filter_map(|(i, a)| func(i, a)).collect()
2614		}
2615	}
2616
2617	impl RefTraversableWithIndex for VecBrand {
2618		/// Traverses the vector by reference with index.
2619		#[document_signature]
2620		///
2621		#[document_type_parameters(
2622			"The lifetime of the elements.",
2623			"The type of the input elements.",
2624			"The type of the output elements.",
2625			"The applicative functor brand."
2626		)]
2627		///
2628		#[document_parameters("The function to apply.", "The vector to traverse.")]
2629		///
2630		#[document_returns("The combined result in the applicative context.")]
2631		///
2632		#[document_examples]
2633		///
2634		/// ```
2635		/// use fp_library::{
2636		/// 	brands::*,
2637		/// 	functions::*,
2638		/// };
2639		///
2640		/// let v = vec![10, 20, 30];
2641		/// let result: Option<Vec<String>> =
2642		/// 	explicit::traverse_with_index::<RcFnBrand, VecBrand, _, _, OptionBrand, _, _>(
2643		/// 		|i, x: &i32| Some(format!("{}:{}", i, x)),
2644		/// 		&v,
2645		/// 	);
2646		/// assert_eq!(result, Some(vec!["0:10".to_string(), "1:20".to_string(), "2:30".to_string()]));
2647		/// ```
2648		fn ref_traverse_with_index<'a, A: 'a + Clone, B: 'a + Clone, M: Applicative>(
2649			f: impl Fn(usize, &A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
2650			ta: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
2651		) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)>)
2652		where
2653			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
2654			Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
2655			let len = ta.len();
2656			ta.iter().enumerate().fold(
2657				M::pure::<Vec<B>>(Vec::with_capacity(len)),
2658				|acc: Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Vec<B>>), (i, a)| {
2659					M::lift2(
2660						|mut v: Vec<B>, b: B| {
2661							v.push(b);
2662							v
2663						},
2664						acc,
2665						f(i, a),
2666					)
2667				},
2668			)
2669		}
2670	}
2671
2672	// -- By-reference monadic trait implementations --
2673
2674	impl RefPointed for VecBrand {
2675		/// Creates a singleton vector from a reference by cloning.
2676		#[document_signature]
2677		///
2678		#[document_type_parameters("The lifetime of the value.", "The type of the value.")]
2679		///
2680		#[document_parameters("The reference to the value to wrap.")]
2681		///
2682		#[document_returns("A singleton vector containing a clone of the value.")]
2683		///
2684		#[document_examples]
2685		///
2686		/// ```
2687		/// use fp_library::{
2688		/// 	brands::*,
2689		/// 	functions::*,
2690		/// };
2691		///
2692		/// let x = 42;
2693		/// let v: Vec<i32> = ref_pure::<VecBrand, _>(&x);
2694		/// assert_eq!(v, vec![42]);
2695		/// ```
2696		fn ref_pure<'a, A: Clone + 'a>(
2697			a: &A
2698		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
2699			vec![a.clone()]
2700		}
2701	}
2702
2703	impl RefLift for VecBrand {
2704		/// Combines two vectors with a by-reference binary function (Cartesian product).
2705		#[document_signature]
2706		///
2707		#[document_type_parameters(
2708			"The lifetime of the values.",
2709			"The type of the first input.",
2710			"The type of the second input.",
2711			"The type of the output."
2712		)]
2713		///
2714		#[document_parameters(
2715			"The binary function receiving references.",
2716			"The first vector.",
2717			"The second vector."
2718		)]
2719		///
2720		#[document_returns("A new vector with the combined results.")]
2721		///
2722		#[document_examples]
2723		///
2724		/// ```
2725		/// use fp_library::{
2726		/// 	brands::*,
2727		/// 	functions::*,
2728		/// };
2729		///
2730		/// let v = explicit::lift2::<VecBrand, _, _, _, _, _, _>(
2731		/// 	|a: &i32, b: &String| format!("{}{}", a, b),
2732		/// 	&vec![1, 2],
2733		/// 	&vec!["a".to_string(), "b".to_string()],
2734		/// );
2735		/// assert_eq!(v, vec!["1a".to_string(), "1b".to_string(), "2a".to_string(), "2b".to_string()]);
2736		/// ```
2737		fn ref_lift2<'a, A: 'a, B: 'a, C: 'a>(
2738			func: impl Fn(&A, &B) -> C + 'a,
2739			fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
2740			fb: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
2741		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) {
2742			let func = &func;
2743			fa.iter().flat_map(|a| fb.iter().map(move |b| func(a, b))).collect()
2744		}
2745	}
2746
2747	impl RefSemiapplicative for VecBrand {
2748		/// Applies wrapped by-ref functions to values (Cartesian product).
2749		#[document_signature]
2750		///
2751		#[document_type_parameters(
2752			"The lifetime of the values.",
2753			"The brand of the cloneable function wrapper.",
2754			"The type of the input values.",
2755			"The type of the output values."
2756		)]
2757		///
2758		#[document_parameters(
2759			"The vector containing the by-ref functions.",
2760			"The vector containing the values."
2761		)]
2762		///
2763		#[document_returns("A new vector with each function applied to each value by reference.")]
2764		///
2765		#[document_examples]
2766		///
2767		/// ```
2768		/// use fp_library::{
2769		/// 	brands::*,
2770		/// 	classes::*,
2771		/// 	functions::*,
2772		/// };
2773		///
2774		/// let f1: std::rc::Rc<dyn Fn(&i32) -> i32> = std::rc::Rc::new(|x: &i32| *x + 1);
2775		/// let f2: std::rc::Rc<dyn Fn(&i32) -> i32> = std::rc::Rc::new(|x: &i32| *x * 2);
2776		/// let result = ref_apply::<RcFnBrand, VecBrand, _, _>(&vec![f1, f2], &vec![10, 20]);
2777		/// assert_eq!(result, vec![11, 21, 20, 40]);
2778		/// ```
2779		fn ref_apply<'a, FnBrand: 'a + CloneFn<Ref>, A: 'a, B: 'a>(
2780			ff: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneFn<Ref>>::Of<'a, A, B>>),
2781			fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
2782		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
2783			ff.iter().flat_map(|f| fa.iter().map(move |a| (**f)(a))).collect()
2784		}
2785	}
2786
2787	impl RefSemimonad for VecBrand {
2788		/// Chains vector computations by reference (`flat_map` with `&A`).
2789		#[document_signature]
2790		///
2791		#[document_type_parameters(
2792			"The lifetime of the values.",
2793			"The type of the input values.",
2794			"The type of the output values."
2795		)]
2796		///
2797		#[document_parameters(
2798			"The input vector.",
2799			"The function to apply to each element by reference."
2800		)]
2801		///
2802		#[document_returns("A new vector with the results flattened.")]
2803		///
2804		#[document_examples]
2805		///
2806		/// ```
2807		/// use fp_library::{
2808		/// 	brands::*,
2809		/// 	functions::*,
2810		/// };
2811		///
2812		/// let v = vec![1, 2, 3];
2813		/// let result: Vec<i32> = explicit::bind::<VecBrand, _, _, _, _>(&v, |x: &i32| vec![*x, *x * 10]);
2814		/// assert_eq!(result, vec![1, 10, 2, 20, 3, 30]);
2815		/// ```
2816		fn ref_bind<'a, A: 'a, B: 'a>(
2817			fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
2818			f: impl Fn(&A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
2819		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
2820			fa.iter().flat_map(f).collect()
2821		}
2822	}
2823
2824	// -- Parallel by-reference trait implementations --
2825
2826	impl ParRefFunctor for VecBrand {
2827		#[document_signature]
2828		#[document_type_parameters(
2829			"The lifetime.",
2830			"The input element type.",
2831			"The output element type."
2832		)]
2833		#[document_parameters("The function. Must be `Send + Sync`.", "The vector.")]
2834		#[document_returns("A new vector with mapped elements.")]
2835		#[document_examples]
2836		///
2837		/// ```
2838		/// use fp_library::{
2839		/// 	brands::VecBrand,
2840		/// 	classes::par_ref_functor::ParRefFunctor,
2841		/// };
2842		/// let result = VecBrand::par_ref_map(|x: &i32| x * 2, &vec![1, 2, 3]);
2843		/// assert_eq!(result, vec![2, 4, 6]);
2844		/// ```
2845		fn par_ref_map<'a, A: Send + Sync + 'a, B: Send + 'a>(
2846			f: impl Fn(&A) -> B + Send + Sync + 'a,
2847			fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
2848		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
2849			#[cfg(feature = "rayon")]
2850			{
2851				use rayon::prelude::*;
2852				fa.par_iter().map(f).collect()
2853			}
2854			#[cfg(not(feature = "rayon"))]
2855			fa.iter().map(f).collect()
2856		}
2857	}
2858
2859	impl ParRefFoldable for VecBrand {
2860		#[document_signature]
2861		#[document_type_parameters("The lifetime.", "The element type.", "The monoid type.")]
2862		#[document_parameters("The function. Must be `Send + Sync`.", "The vector.")]
2863		#[document_returns("The combined monoid value.")]
2864		#[document_examples]
2865		///
2866		/// ```
2867		/// use fp_library::{
2868		/// 	brands::VecBrand,
2869		/// 	classes::par_ref_foldable::ParRefFoldable,
2870		/// };
2871		/// let result = VecBrand::par_ref_fold_map(|x: &i32| x.to_string(), &vec![1, 2, 3]);
2872		/// assert_eq!(result, "123");
2873		/// ```
2874		fn par_ref_fold_map<'a, A: Send + Sync + 'a, M: Monoid + Send + 'a>(
2875			f: impl Fn(&A) -> M + Send + Sync + 'a,
2876			fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
2877		) -> M {
2878			#[cfg(feature = "rayon")]
2879			{
2880				use rayon::prelude::*;
2881				fa.par_iter().map(f).reduce(Monoid::empty, Semigroup::append)
2882			}
2883			#[cfg(not(feature = "rayon"))]
2884			fa.iter().map(f).fold(Monoid::empty(), |acc, m| Semigroup::append(acc, m))
2885		}
2886	}
2887
2888	impl ParRefFilterable for VecBrand {
2889		#[document_signature]
2890		#[document_type_parameters("The lifetime.", "The input type.", "The output type.")]
2891		#[document_parameters("The function. Must be `Send + Sync`.", "The vector.")]
2892		#[document_returns("A new vector with filtered and mapped elements.")]
2893		#[document_examples]
2894		///
2895		/// ```
2896		/// use fp_library::{
2897		/// 	brands::VecBrand,
2898		/// 	classes::par_ref_filterable::ParRefFilterable,
2899		/// };
2900		/// let result = VecBrand::par_ref_filter_map(
2901		/// 	|x: &i32| if *x > 2 { Some(x.to_string()) } else { None },
2902		/// 	&vec![1, 2, 3, 4],
2903		/// );
2904		/// assert_eq!(result, vec!["3", "4"]);
2905		/// ```
2906		fn par_ref_filter_map<'a, A: Send + Sync + 'a, B: Send + 'a>(
2907			f: impl Fn(&A) -> Option<B> + Send + Sync + 'a,
2908			fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
2909		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
2910			#[cfg(feature = "rayon")]
2911			{
2912				use rayon::prelude::*;
2913				fa.par_iter().filter_map(f).collect()
2914			}
2915			#[cfg(not(feature = "rayon"))]
2916			fa.iter().filter_map(f).collect()
2917		}
2918	}
2919
2920	impl ParRefFunctorWithIndex for VecBrand {
2921		#[document_signature]
2922		#[document_type_parameters("The lifetime.", "The input type.", "The output type.")]
2923		#[document_parameters("The function with index. Must be `Send + Sync`.", "The vector.")]
2924		#[document_returns("A new vector with mapped elements.")]
2925		#[document_examples]
2926		///
2927		/// ```
2928		/// use fp_library::{
2929		/// 	brands::VecBrand,
2930		/// 	classes::par_ref_functor_with_index::ParRefFunctorWithIndex,
2931		/// };
2932		/// let result =
2933		/// 	VecBrand::par_ref_map_with_index(|i, x: &i32| format!("{}:{}", i, x), &vec![10, 20]);
2934		/// assert_eq!(result, vec!["0:10", "1:20"]);
2935		/// ```
2936		fn par_ref_map_with_index<'a, A: Send + Sync + 'a, B: Send + 'a>(
2937			f: impl Fn(usize, &A) -> B + Send + Sync + 'a,
2938			fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
2939		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
2940			#[cfg(feature = "rayon")]
2941			{
2942				use rayon::prelude::*;
2943				fa.par_iter().enumerate().map(|(i, a)| f(i, a)).collect()
2944			}
2945			#[cfg(not(feature = "rayon"))]
2946			fa.iter().enumerate().map(|(i, a)| f(i, a)).collect()
2947		}
2948	}
2949
2950	impl ParRefFoldableWithIndex for VecBrand {
2951		#[document_signature]
2952		#[document_type_parameters("The lifetime.", "The element type.", "The monoid type.")]
2953		#[document_parameters("The function with index. Must be `Send + Sync`.", "The vector.")]
2954		#[document_returns("The combined monoid value.")]
2955		#[document_examples]
2956		///
2957		/// ```
2958		/// use fp_library::{
2959		/// 	brands::VecBrand,
2960		/// 	classes::par_ref_foldable_with_index::ParRefFoldableWithIndex,
2961		/// };
2962		/// let result =
2963		/// 	VecBrand::par_ref_fold_map_with_index(|i, x: &i32| format!("{}:{}", i, x), &vec![10, 20]);
2964		/// assert_eq!(result, "0:101:20");
2965		/// ```
2966		fn par_ref_fold_map_with_index<'a, A: Send + Sync + 'a, M: Monoid + Send + 'a>(
2967			f: impl Fn(usize, &A) -> M + Send + Sync + 'a,
2968			fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
2969		) -> M {
2970			#[cfg(feature = "rayon")]
2971			{
2972				use rayon::prelude::*;
2973				fa.par_iter()
2974					.enumerate()
2975					.map(|(i, a)| f(i, a))
2976					.reduce(Monoid::empty, Semigroup::append)
2977			}
2978			#[cfg(not(feature = "rayon"))]
2979			fa.iter()
2980				.enumerate()
2981				.map(|(i, a)| f(i, a))
2982				.fold(Monoid::empty(), |acc, m| Semigroup::append(acc, m))
2983		}
2984	}
2985
2986	impl ParRefFilterableWithIndex for VecBrand {
2987		#[document_signature]
2988		#[document_type_parameters("The lifetime.", "The input type.", "The output type.")]
2989		#[document_parameters("The function with index. Must be `Send + Sync`.", "The vector.")]
2990		#[document_returns("A new vector with filtered and mapped elements.")]
2991		#[document_examples]
2992		///
2993		/// ```
2994		/// use fp_library::{
2995		/// 	brands::VecBrand,
2996		/// 	classes::par_ref_filterable_with_index::ParRefFilterableWithIndex,
2997		/// };
2998		/// let v = vec![10, 20, 30, 40, 50];
2999		/// let result = VecBrand::par_ref_filter_map_with_index(
3000		/// 	|i, x: &i32| if i % 2 == 0 { Some(x.to_string()) } else { None },
3001		/// 	&v,
3002		/// );
3003		/// assert_eq!(result, vec!["10", "30", "50"]);
3004		/// ```
3005		fn par_ref_filter_map_with_index<'a, A: Send + Sync + 'a, B: Send + 'a>(
3006			f: impl Fn(usize, &A) -> Option<B> + Send + Sync + 'a,
3007			fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
3008		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
3009			#[cfg(feature = "rayon")]
3010			{
3011				use rayon::prelude::*;
3012				fa.par_iter().enumerate().filter_map(|(i, a)| f(i, a)).collect()
3013			}
3014			#[cfg(not(feature = "rayon"))]
3015			fa.iter().enumerate().filter_map(|(i, a)| f(i, a)).collect()
3016		}
3017	}
3018}
3019
3020#[cfg(test)]
3021mod tests {
3022
3023	use {
3024		crate::{
3025			brands::*,
3026			classes::*,
3027			functions::*,
3028		},
3029		quickcheck_macros::quickcheck,
3030	};
3031
3032	// Functor Laws
3033
3034	/// Tests the identity law for Functor.
3035	#[quickcheck]
3036	fn functor_identity(x: Vec<i32>) -> bool {
3037		explicit::map::<VecBrand, _, _, _, _>(identity, x.clone()) == x
3038	}
3039
3040	/// Tests the composition law for Functor.
3041	#[quickcheck]
3042	fn functor_composition(x: Vec<i32>) -> bool {
3043		let f = |x: i32| x.wrapping_add(1);
3044		let g = |x: i32| x.wrapping_mul(2);
3045		explicit::map::<VecBrand, _, _, _, _>(compose(f, g), x.clone())
3046			== explicit::map::<VecBrand, _, _, _, _>(f, explicit::map::<VecBrand, _, _, _, _>(g, x))
3047	}
3048
3049	// Applicative Laws
3050
3051	/// Tests the identity law for Applicative.
3052	#[quickcheck]
3053	fn applicative_identity(v: Vec<i32>) -> bool {
3054		apply(pure::<VecBrand, _>(<RcFnBrand as LiftFn>::new(identity)), v.clone()) == v
3055	}
3056
3057	/// Tests the homomorphism law for Applicative.
3058	#[quickcheck]
3059	fn applicative_homomorphism(x: i32) -> bool {
3060		let f = |x: i32| x.wrapping_mul(2);
3061		apply(pure::<VecBrand, _>(<RcFnBrand as LiftFn>::new(f)), pure::<VecBrand, _>(x))
3062			== pure::<VecBrand, _>(f(x))
3063	}
3064
3065	/// Tests the composition law for Applicative.
3066	#[quickcheck]
3067	fn applicative_composition(
3068		w: Vec<i32>,
3069		u_seeds: Vec<i32>,
3070		v_seeds: Vec<i32>,
3071	) -> bool {
3072		let u_fns: Vec<_> = u_seeds
3073			.iter()
3074			.map(|&i| <RcFnBrand as LiftFn>::new(move |x: i32| x.wrapping_add(i)))
3075			.collect();
3076		let v_fns: Vec<_> = v_seeds
3077			.iter()
3078			.map(|&i| <RcFnBrand as LiftFn>::new(move |x: i32| x.wrapping_mul(i)))
3079			.collect();
3080
3081		// RHS: u <*> (v <*> w)
3082		let vw = apply(v_fns.clone(), w.clone());
3083		let rhs = apply(u_fns.clone(), vw);
3084
3085		// LHS: pure(compose) <*> u <*> v <*> w
3086		// equivalent to (u . v) <*> w
3087		// We construct (u . v) manually as the cartesian product of compositions
3088		let uv_fns: Vec<_> = u_fns
3089			.iter()
3090			.flat_map(|uf| {
3091				v_fns.iter().map(move |vf| {
3092					let uf = uf.clone();
3093					let vf = vf.clone();
3094					<RcFnBrand as LiftFn>::new(move |x| uf(vf(x)))
3095				})
3096			})
3097			.collect();
3098
3099		let lhs = apply(uv_fns, w);
3100
3101		lhs == rhs
3102	}
3103
3104	/// Tests the interchange law for Applicative.
3105	#[quickcheck]
3106	fn applicative_interchange(y: i32) -> bool {
3107		// u <*> pure y = pure ($ y) <*> u
3108		let f = |x: i32| x.wrapping_mul(2);
3109		let u = vec![<RcFnBrand as LiftFn>::new(f)];
3110
3111		let lhs = apply(u.clone(), pure::<VecBrand, _>(y));
3112
3113		let rhs_fn = <RcFnBrand as LiftFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
3114		let rhs = apply(pure::<VecBrand, _>(rhs_fn), u);
3115
3116		lhs == rhs
3117	}
3118
3119	// Semigroup Laws
3120
3121	/// Tests the associativity law for Semigroup.
3122	#[quickcheck]
3123	fn semigroup_associativity(
3124		a: Vec<i32>,
3125		b: Vec<i32>,
3126		c: Vec<i32>,
3127	) -> bool {
3128		append(a.clone(), append(b.clone(), c.clone())) == append(append(a, b), c)
3129	}
3130
3131	// Monoid Laws
3132
3133	/// Tests the left identity law for Monoid.
3134	#[quickcheck]
3135	fn monoid_left_identity(a: Vec<i32>) -> bool {
3136		append(empty::<Vec<i32>>(), a.clone()) == a
3137	}
3138
3139	/// Tests the right identity law for Monoid.
3140	#[quickcheck]
3141	fn monoid_right_identity(a: Vec<i32>) -> bool {
3142		append(a.clone(), empty::<Vec<i32>>()) == a
3143	}
3144
3145	// Monad Laws
3146
3147	/// Tests the left identity law for Monad.
3148	#[quickcheck]
3149	fn monad_left_identity(a: i32) -> bool {
3150		let f = |x: i32| vec![x.wrapping_mul(2)];
3151		explicit::bind::<VecBrand, _, _, _, _>(pure::<VecBrand, _>(a), f) == f(a)
3152	}
3153
3154	/// Tests the right identity law for Monad.
3155	#[quickcheck]
3156	fn monad_right_identity(m: Vec<i32>) -> bool {
3157		explicit::bind::<VecBrand, _, _, _, _>(m.clone(), pure::<VecBrand, _>) == m
3158	}
3159
3160	/// Tests the associativity law for Monad.
3161	#[quickcheck]
3162	fn monad_associativity(m: Vec<i32>) -> bool {
3163		let f = |x: i32| vec![x.wrapping_mul(2)];
3164		let g = |x: i32| vec![x.wrapping_add(1)];
3165		explicit::bind::<VecBrand, _, _, _, _>(
3166			explicit::bind::<VecBrand, _, _, _, _>(m.clone(), f),
3167			g,
3168		) == explicit::bind::<VecBrand, _, _, _, _>(m, |x| {
3169			explicit::bind::<VecBrand, _, _, _, _>(f(x), g)
3170		})
3171	}
3172
3173	// Edge Cases
3174
3175	/// Tests `map` on an empty vector.
3176	#[test]
3177	fn map_empty() {
3178		assert_eq!(
3179			explicit::map::<VecBrand, _, _, _, _>(|x: i32| x + 1, vec![] as Vec<i32>),
3180			vec![] as Vec<i32>
3181		);
3182	}
3183
3184	/// Tests `bind` on an empty vector.
3185	#[test]
3186	fn bind_empty() {
3187		assert_eq!(
3188			explicit::bind::<VecBrand, _, _, _, _>(vec![] as Vec<i32>, |x: i32| vec![x + 1]),
3189			vec![] as Vec<i32>
3190		);
3191	}
3192
3193	/// Tests `bind` returning an empty vector.
3194	#[test]
3195	fn bind_returning_empty() {
3196		assert_eq!(
3197			explicit::bind::<VecBrand, _, _, _, _>(vec![1, 2, 3], |_| vec![] as Vec<i32>),
3198			vec![] as Vec<i32>
3199		);
3200	}
3201
3202	/// Tests `fold_right` on an empty vector.
3203	#[test]
3204	fn fold_right_empty() {
3205		assert_eq!(
3206			crate::functions::explicit::fold_right::<RcFnBrand, VecBrand, _, _, _, _>(
3207				|x: i32, acc| x + acc,
3208				0,
3209				vec![]
3210			),
3211			0
3212		);
3213	}
3214
3215	/// Tests `fold_left` on an empty vector.
3216	#[test]
3217	fn fold_left_empty() {
3218		assert_eq!(
3219			crate::functions::explicit::fold_left::<RcFnBrand, VecBrand, _, _, _, _>(
3220				|acc, x: i32| acc + x,
3221				0,
3222				vec![]
3223			),
3224			0
3225		);
3226	}
3227
3228	/// Tests `traverse` on an empty vector.
3229	#[test]
3230	fn traverse_empty() {
3231		use crate::brands::OptionBrand;
3232		assert_eq!(
3233			crate::classes::traversable::traverse::<VecBrand, _, _, OptionBrand>(
3234				|x: i32| Some(x + 1),
3235				vec![]
3236			),
3237			Some(vec![])
3238		);
3239	}
3240
3241	/// Tests `traverse` returning an empty vector.
3242	#[test]
3243	fn traverse_returning_empty() {
3244		use crate::brands::OptionBrand;
3245		assert_eq!(
3246			crate::classes::traversable::traverse::<VecBrand, _, _, OptionBrand>(
3247				|_: i32| None::<i32>,
3248				vec![1, 2, 3]
3249			),
3250			None
3251		);
3252	}
3253
3254	/// Tests `construct` with an empty tail.
3255	#[test]
3256	fn construct_empty_tail() {
3257		assert_eq!(VecBrand::construct(1, vec![]), vec![1]);
3258	}
3259
3260	/// Tests `deconstruct` on an empty slice.
3261	#[test]
3262	fn deconstruct_empty() {
3263		assert_eq!(VecBrand::deconstruct::<i32>(&[]), None);
3264	}
3265
3266	// Parallel Trait Tests
3267
3268	/// Tests `par_map` on a vector.
3269	#[test]
3270	fn par_map_basic() {
3271		let v = vec![1, 2, 3];
3272		let result: Vec<i32> = par_map::<VecBrand, _, _>(|x: i32| x * 2, v);
3273		assert_eq!(result, vec![2, 4, 6]);
3274	}
3275
3276	/// Tests `par_filter` on a vector.
3277	#[test]
3278	fn par_filter_basic() {
3279		let v = vec![1, 2, 3, 4, 5];
3280		let result: Vec<i32> = par_filter::<VecBrand, _>(|x: &i32| x % 2 == 0, v);
3281		assert_eq!(result, vec![2, 4]);
3282	}
3283
3284	/// Tests `par_filter_map` on a vector.
3285	#[test]
3286	fn par_filter_map_basic() {
3287		let v = vec![1, 2, 3, 4, 5];
3288		let result: Vec<i32> = par_filter_map::<VecBrand, _, _>(
3289			|x: i32| if x % 2 == 0 { Some(x * 10) } else { None },
3290			v,
3291		);
3292		assert_eq!(result, vec![20, 40]);
3293	}
3294
3295	/// Tests `par_compact` on a vector of options.
3296	#[test]
3297	fn par_compact_basic() {
3298		let v = vec![Some(1), None, Some(3), None, Some(5)];
3299		let result: Vec<i32> = par_compact::<VecBrand, _>(v);
3300		assert_eq!(result, vec![1, 3, 5]);
3301	}
3302
3303	/// Tests `par_separate` on a vector of results.
3304	#[test]
3305	fn par_separate_basic() {
3306		let v: Vec<Result<i32, &str>> = vec![Ok(1), Err("a"), Ok(3), Err("b")];
3307		let (errs, oks): (Vec<&str>, Vec<i32>) = par_separate::<VecBrand, _, _>(v);
3308		assert_eq!(errs, vec!["a", "b"]);
3309		assert_eq!(oks, vec![1, 3]);
3310	}
3311
3312	/// Tests `par_map_with_index` on a vector.
3313	#[test]
3314	fn par_map_with_index_basic() {
3315		let v = vec![10, 20, 30];
3316		let result: Vec<i32> = par_map_with_index::<VecBrand, _, _>(|i, x: i32| x + i as i32, v);
3317		assert_eq!(result, vec![10, 21, 32]);
3318	}
3319
3320	/// Tests `par_fold_map` on an empty vector.
3321	#[test]
3322	fn par_fold_map_empty() {
3323		let v: Vec<i32> = vec![];
3324		assert_eq!(par_fold_map::<VecBrand, _, _>(|x: i32| x.to_string(), v), "".to_string());
3325	}
3326
3327	/// Tests `par_fold_map` on multiple elements.
3328	#[test]
3329	fn par_fold_map_multiple() {
3330		let v = vec![1, 2, 3];
3331		assert_eq!(par_fold_map::<VecBrand, _, _>(|x: i32| x.to_string(), v), "123".to_string());
3332	}
3333
3334	/// Tests `par_fold_map_with_index` on a vector.
3335	#[test]
3336	fn par_fold_map_with_index_basic() {
3337		let v = vec![10, 20, 30];
3338		let result: String =
3339			par_fold_map_with_index::<VecBrand, _, _>(|i, x: i32| format!("{i}:{x}"), v);
3340		assert_eq!(result, "0:101:202:30");
3341	}
3342
3343	// Filterable Laws
3344
3345	/// Tests `filterMap identity ≡ compact`.
3346	#[quickcheck]
3347	fn filterable_filter_map_identity(x: Vec<Option<i32>>) -> bool {
3348		explicit::filter_map::<VecBrand, _, _, _, _>(identity, x.clone())
3349			== explicit::compact::<VecBrand, _, _, _>(x)
3350	}
3351
3352	/// Tests `filterMap Just ≡ identity`.
3353	#[quickcheck]
3354	fn filterable_filter_map_just(x: Vec<i32>) -> bool {
3355		explicit::filter_map::<VecBrand, _, _, _, _>(Some, x.clone()) == x
3356	}
3357
3358	/// Tests `filterMap (l <=< r) ≡ filterMap l <<< filterMap r`.
3359	#[quickcheck]
3360	fn filterable_filter_map_composition(x: Vec<i32>) -> bool {
3361		let r = |i: i32| if i % 2 == 0 { Some(i) } else { None };
3362		let l = |i: i32| if i > 5 { Some(i) } else { None };
3363		let composed = |i| explicit::bind::<OptionBrand, _, _, _, _>(r(i), l);
3364
3365		explicit::filter_map::<VecBrand, _, _, _, _>(composed, x.clone())
3366			== explicit::filter_map::<VecBrand, _, _, _, _>(
3367				l,
3368				explicit::filter_map::<VecBrand, _, _, _, _>(r, x),
3369			)
3370	}
3371
3372	/// Tests `filter ≡ filterMap <<< maybeBool`.
3373	#[quickcheck]
3374	fn filterable_filter_consistency(x: Vec<i32>) -> bool {
3375		let p = |i: i32| i % 2 == 0;
3376		let maybe_bool = |i| if p(i) { Some(i) } else { None };
3377
3378		explicit::filter::<VecBrand, _, _, _>(p, x.clone())
3379			== explicit::filter_map::<VecBrand, _, _, _, _>(maybe_bool, x)
3380	}
3381
3382	/// Tests `partitionMap identity ≡ separate`.
3383	#[quickcheck]
3384	fn filterable_partition_map_identity(x: Vec<Result<i32, i32>>) -> bool {
3385		explicit::partition_map::<VecBrand, _, _, _, _, _>(identity, x.clone())
3386			== explicit::separate::<VecBrand, _, _, _, _>(x)
3387	}
3388
3389	/// Tests `partitionMap Right ≡ identity` (on the right side).
3390	#[quickcheck]
3391	fn filterable_partition_map_right_identity(x: Vec<i32>) -> bool {
3392		let (_, oks) = explicit::partition_map::<VecBrand, _, _, _, _, _>(Ok::<_, i32>, x.clone());
3393		oks == x
3394	}
3395
3396	/// Tests `partitionMap Left ≡ identity` (on the left side).
3397	#[quickcheck]
3398	fn filterable_partition_map_left_identity(x: Vec<i32>) -> bool {
3399		let (errs, _) =
3400			explicit::partition_map::<VecBrand, _, _, _, _, _>(Err::<i32, _>, x.clone());
3401		errs == x
3402	}
3403
3404	/// Tests `f <<< partition ≡ partitionMap <<< eitherBool`.
3405	#[quickcheck]
3406	fn filterable_partition_consistency(x: Vec<i32>) -> bool {
3407		let p = |i: i32| i % 2 == 0;
3408		let either_bool = |i| if p(i) { Ok(i) } else { Err(i) };
3409
3410		let (not_satisfied, satisfied) = explicit::partition::<VecBrand, _, _, _>(p, x.clone());
3411		let (errs, oks) = explicit::partition_map::<VecBrand, _, _, _, _, _>(either_bool, x);
3412
3413		satisfied == oks && not_satisfied == errs
3414	}
3415
3416	// Witherable Laws
3417
3418	/// Tests `wither (pure <<< Just) ≡ pure`.
3419	#[quickcheck]
3420	fn witherable_identity(x: Vec<i32>) -> bool {
3421		explicit::wither::<RcFnBrand, VecBrand, OptionBrand, _, _, _, _>(
3422			|i| Some(Some(i)),
3423			x.clone(),
3424		) == Some(x)
3425	}
3426
3427	/// Tests `wilt p ≡ map separate <<< traverse p`.
3428	#[quickcheck]
3429	fn witherable_wilt_consistency(x: Vec<i32>) -> bool {
3430		let p = |i: i32| Some(if i % 2 == 0 { Ok(i) } else { Err(i) });
3431
3432		let lhs = explicit::wilt::<RcFnBrand, VecBrand, OptionBrand, _, _, _, _, _>(p, x.clone());
3433		let rhs = crate::dispatch::functor::explicit::map::<OptionBrand, _, _, _, _>(
3434			explicit::separate::<VecBrand, _, _, _, _>,
3435			explicit::traverse::<RcFnBrand, VecBrand, _, _, OptionBrand, _, _>(p, x),
3436		);
3437
3438		lhs == rhs
3439	}
3440
3441	/// Tests `wither p ≡ map compact <<< traverse p`.
3442	#[quickcheck]
3443	fn witherable_wither_consistency(x: Vec<i32>) -> bool {
3444		let p = |i: i32| Some(if i % 2 == 0 { Some(i) } else { None });
3445
3446		let lhs = explicit::wither::<RcFnBrand, VecBrand, OptionBrand, _, _, _, _>(p, x.clone());
3447		let rhs = crate::dispatch::functor::explicit::map::<OptionBrand, _, _, _, _>(
3448			explicit::compact::<VecBrand, _, _, _>,
3449			explicit::traverse::<RcFnBrand, VecBrand, _, _, OptionBrand, _, _>(p, x),
3450		);
3451
3452		lhs == rhs
3453	}
3454
3455	// Alt Laws
3456
3457	/// Tests the associativity law for Alt.
3458	#[quickcheck]
3459	fn alt_associativity(
3460		x: Vec<i32>,
3461		y: Vec<i32>,
3462		z: Vec<i32>,
3463	) -> bool {
3464		explicit::alt::<VecBrand, _, _, _>(
3465			explicit::alt::<VecBrand, _, _, _>(x.clone(), y.clone()),
3466			z.clone(),
3467		) == explicit::alt::<VecBrand, _, _, _>(x, explicit::alt::<VecBrand, _, _, _>(y, z))
3468	}
3469
3470	/// Tests the distributivity law for Alt.
3471	#[quickcheck]
3472	fn alt_distributivity(
3473		x: Vec<i32>,
3474		y: Vec<i32>,
3475	) -> bool {
3476		let f = |i: i32| i.wrapping_mul(2).wrapping_add(1);
3477		explicit::map::<VecBrand, _, _, _, _>(
3478			f,
3479			explicit::alt::<VecBrand, _, _, _>(x.clone(), y.clone()),
3480		) == explicit::alt::<VecBrand, _, _, _>(
3481			explicit::map::<VecBrand, _, _, _, _>(f, x),
3482			explicit::map::<VecBrand, _, _, _, _>(f, y),
3483		)
3484	}
3485
3486	// Plus Laws
3487
3488	/// Tests the left identity law for Plus.
3489	#[quickcheck]
3490	fn plus_left_identity(x: Vec<i32>) -> bool {
3491		explicit::alt::<VecBrand, _, _, _>(plus_empty::<VecBrand, i32>(), x.clone()) == x
3492	}
3493
3494	/// Tests the right identity law for Plus.
3495	#[quickcheck]
3496	fn plus_right_identity(x: Vec<i32>) -> bool {
3497		explicit::alt::<VecBrand, _, _, _>(x.clone(), plus_empty::<VecBrand, i32>()) == x
3498	}
3499
3500	/// Tests the annihilation law for Plus.
3501	#[test]
3502	fn plus_annihilation() {
3503		let f = |i: i32| i.wrapping_mul(2);
3504		assert_eq!(
3505			explicit::map::<VecBrand, _, _, _, _>(f, plus_empty::<VecBrand, i32>()),
3506			plus_empty::<VecBrand, i32>(),
3507		);
3508	}
3509
3510	// Compactable Laws (Plus-dependent)
3511
3512	/// Tests the functor identity law for Compactable.
3513	#[quickcheck]
3514	fn compactable_functor_identity(fa: Vec<i32>) -> bool {
3515		explicit::compact::<VecBrand, _, _, _>(explicit::map::<VecBrand, _, _, _, _>(
3516			Some,
3517			fa.clone(),
3518		)) == fa
3519	}
3520
3521	/// Tests the Plus annihilation (empty) law for Compactable.
3522	#[test]
3523	fn compactable_plus_annihilation_empty() {
3524		assert_eq!(
3525			explicit::compact::<VecBrand, _, _, _>(plus_empty::<VecBrand, Option<i32>>()),
3526			plus_empty::<VecBrand, i32>(),
3527		);
3528	}
3529
3530	/// Tests the Plus annihilation (map) law for Compactable.
3531	#[quickcheck]
3532	fn compactable_plus_annihilation_map(xs: Vec<i32>) -> bool {
3533		explicit::compact::<VecBrand, _, _, _>(explicit::map::<VecBrand, _, _, _, _>(
3534			|_: i32| None::<i32>,
3535			xs,
3536		)) == plus_empty::<VecBrand, i32>()
3537	}
3538
3539	// Edge Cases
3540
3541	/// Tests `compact` on an empty vector.
3542	#[test]
3543	fn compact_empty() {
3544		assert_eq!(
3545			explicit::compact::<VecBrand, i32, _, _>(vec![] as Vec<Option<i32>>),
3546			vec![] as Vec<i32>
3547		);
3548	}
3549
3550	/// Tests `compact` on a vector with `None`.
3551	#[test]
3552	fn compact_with_none() {
3553		assert_eq!(
3554			explicit::compact::<VecBrand, i32, _, _>(vec![Some(1), None, Some(2)]),
3555			vec![1, 2]
3556		);
3557	}
3558
3559	/// Tests `separate` on an empty vector.
3560	#[test]
3561	fn separate_empty() {
3562		let (errs, oks) =
3563			explicit::separate::<VecBrand, i32, i32, _, _>(vec![] as Vec<Result<i32, i32>>);
3564		assert_eq!(oks, vec![] as Vec<i32>);
3565		assert_eq!(errs, vec![] as Vec<i32>);
3566	}
3567
3568	/// Tests `separate` on a vector with `Ok` and `Err`.
3569	#[test]
3570	fn separate_mixed() {
3571		let (errs, oks) =
3572			explicit::separate::<VecBrand, i32, i32, _, _>(vec![Ok(1), Err(2), Ok(3)]);
3573		assert_eq!(oks, vec![1, 3]);
3574		assert_eq!(errs, vec![2]);
3575	}
3576
3577	/// Tests `partition_map` on an empty vector.
3578	#[test]
3579	fn partition_map_empty() {
3580		let (errs, oks) =
3581			explicit::partition_map::<VecBrand, _, _, _, _, _>(|x: i32| Ok::<i32, i32>(x), vec![]);
3582		assert_eq!(oks, vec![] as Vec<i32>);
3583		assert_eq!(errs, vec![] as Vec<i32>);
3584	}
3585
3586	/// Tests `partition` on an empty vector.
3587	#[test]
3588	fn partition_empty() {
3589		let (not_satisfied, satisfied) =
3590			explicit::partition::<VecBrand, _, _, _>(|x: i32| x > 0, vec![]);
3591		assert_eq!(satisfied, vec![] as Vec<i32>);
3592		assert_eq!(not_satisfied, vec![] as Vec<i32>);
3593	}
3594
3595	/// Tests `filter_map` on an empty vector.
3596	#[test]
3597	fn filter_map_empty() {
3598		assert_eq!(
3599			explicit::filter_map::<VecBrand, i32, _, _, _>(|x: i32| Some(x), vec![]),
3600			vec![] as Vec<i32>
3601		);
3602	}
3603
3604	/// Tests `filter` on an empty vector.
3605	#[test]
3606	fn filter_empty() {
3607		assert_eq!(
3608			explicit::filter::<VecBrand, _, _, _>(|x: i32| x > 0, vec![]),
3609			vec![] as Vec<i32>
3610		);
3611	}
3612
3613	/// Tests `wilt` on an empty vector.
3614	#[test]
3615	fn wilt_empty() {
3616		let res = explicit::wilt::<RcFnBrand, VecBrand, OptionBrand, _, _, _, _, _>(
3617			|x: i32| Some(Ok::<i32, i32>(x)),
3618			vec![],
3619		);
3620		assert_eq!(res, Some((vec![], vec![])));
3621	}
3622
3623	/// Tests `wither` on an empty vector.
3624	#[test]
3625	fn wither_empty() {
3626		let res = explicit::wither::<RcFnBrand, VecBrand, OptionBrand, _, _, _, _>(
3627			|x: i32| Some(Some(x)),
3628			vec![],
3629		);
3630		assert_eq!(res, Some(vec![]));
3631	}
3632
3633	// Parallel Trait Laws
3634
3635	/// Verifies that `par_fold_map` correctly sums a large vector (100,000 elements).
3636	#[test]
3637	fn test_large_vector_par_fold_map() {
3638		use crate::types::Additive;
3639
3640		let xs: Vec<i32> = (0 .. 100000).collect();
3641		let res = par_fold_map::<VecBrand, _, _>(|x: i32| Additive(x as i64), xs);
3642		assert_eq!(res, Additive(4999950000));
3643	}
3644
3645	/// Property: `par_map` agrees with sequential `map`.
3646	#[quickcheck]
3647	fn prop_par_map_equals_map(xs: Vec<i32>) -> bool {
3648		let f = |x: i32| x.wrapping_add(1);
3649		let seq_res = explicit::map::<VecBrand, _, _, _, _>(f, xs.clone());
3650		let par_res = par_map::<VecBrand, _, _>(f, xs);
3651		seq_res == par_res
3652	}
3653
3654	/// Property: `par_fold_map` agrees with sequential `fold_map`.
3655	#[quickcheck]
3656	fn prop_par_fold_map_equals_fold_map(xs: Vec<i32>) -> bool {
3657		use crate::types::Additive;
3658
3659		let f = |x: i32| Additive(x as i64);
3660		let seq_res =
3661			crate::functions::explicit::fold_map::<crate::brands::RcFnBrand, VecBrand, _, _, _, _>(
3662				f,
3663				xs.clone(),
3664			);
3665		let par_res = par_fold_map::<VecBrand, _, _>(f, xs);
3666		seq_res == par_res
3667	}
3668
3669	/// Property: `par_fold_map` on an empty vector returns the Monoid's empty value.
3670	#[quickcheck]
3671	fn prop_par_fold_map_empty_is_empty(xs: Vec<i32>) -> bool {
3672		use crate::types::Additive;
3673
3674		if !xs.is_empty() {
3675			return true;
3676		}
3677		let par_res = par_fold_map::<VecBrand, _, _>(|x: i32| Additive(x as i64), xs);
3678		par_res == empty::<Additive<i64>>()
3679	}
3680
3681	// MonadRec tests
3682
3683	/// Tests the MonadRec identity law: `tail_rec_m(|a| pure(Done(a)), x) == pure(x)`.
3684	#[quickcheck]
3685	fn monad_rec_identity(x: i32) -> bool {
3686		use {
3687			crate::classes::monad_rec::tail_rec_m,
3688			core::ops::ControlFlow,
3689		};
3690		tail_rec_m::<VecBrand, _, _>(|a| vec![ControlFlow::Break(a)], x) == vec![x]
3691	}
3692
3693	/// Tests a simple linear recursion via `tail_rec_m`.
3694	#[test]
3695	fn monad_rec_linear() {
3696		use {
3697			crate::classes::monad_rec::tail_rec_m,
3698			core::ops::ControlFlow,
3699		};
3700		// Count up to 5
3701		let result = tail_rec_m::<VecBrand, _, _>(
3702			|n| {
3703				if n < 5 { vec![ControlFlow::Continue(n + 1)] } else { vec![ControlFlow::Break(n)] }
3704			},
3705			0,
3706		);
3707		assert_eq!(result, vec![5]);
3708	}
3709
3710	/// Tests branching nondeterminism via `tail_rec_m`.
3711	#[test]
3712	fn monad_rec_branching() {
3713		use {
3714			crate::classes::monad_rec::tail_rec_m,
3715			core::ops::ControlFlow,
3716		};
3717		// Each step either finishes or continues
3718		let result = tail_rec_m::<VecBrand, _, _>(
3719			|n: i32| {
3720				if n < 2 {
3721					vec![ControlFlow::Continue(n + 1), ControlFlow::Break(n * 100)]
3722				} else {
3723					vec![ControlFlow::Break(n * 100)]
3724				}
3725			},
3726			0,
3727		);
3728		// n=0: Loop(1), Done(0)
3729		// n=1: Loop(2), Done(100)
3730		// n=2: Done(200)
3731		assert_eq!(result, vec![0, 100, 200]);
3732	}
3733
3734	/// Tests that `tail_rec_m` handles an empty result from the step function.
3735	#[test]
3736	fn monad_rec_empty() {
3737		use {
3738			crate::classes::monad_rec::tail_rec_m,
3739			core::ops::ControlFlow,
3740		};
3741		let result: Vec<i32> =
3742			tail_rec_m::<VecBrand, _, _>(|_n| Vec::<ControlFlow<i32, i32>>::new(), 0);
3743		assert_eq!(result, Vec::<i32>::new());
3744	}
3745
3746	// Extend Laws
3747
3748	/// Tests basic `extend` on `Vec`: sum of suffixes.
3749	#[test]
3750	fn extend_sum_of_suffixes() {
3751		use crate::classes::extend::extend;
3752		let result = extend::<VecBrand, _, _>(|v: Vec<i32>| v.iter().sum::<i32>(), vec![1, 2, 3]);
3753		assert_eq!(result, vec![6, 5, 3]);
3754	}
3755
3756	/// Extend associativity: `extend(f, extend(g, w)) == extend(|w| f(extend(g, w)), w)`.
3757	#[quickcheck]
3758	fn extend_associativity(w: Vec<i32>) -> bool {
3759		use crate::classes::extend::extend;
3760		let g = |v: Vec<i32>| v.iter().fold(0i32, |a, b| a.wrapping_mul(2).wrapping_add(*b));
3761		let f = |v: Vec<i32>| v.iter().fold(0i32, |a, b| a.wrapping_add(b.wrapping_add(1)));
3762		let lhs = extend::<VecBrand, _, _>(f, extend::<VecBrand, _, _>(g, w.clone()));
3763		let rhs = extend::<VecBrand, _, _>(|w: Vec<i32>| f(extend::<VecBrand, _, _>(g, w)), w);
3764		lhs == rhs
3765	}
3766
3767	/// Tests that `duplicate` produces suffixes.
3768	#[test]
3769	fn extend_duplicate_suffixes() {
3770		use crate::classes::extend::duplicate;
3771		let result = duplicate::<VecBrand, _>(vec![1, 2, 3]);
3772		assert_eq!(result, vec![vec![1, 2, 3], vec![2, 3], vec![3]]);
3773	}
3774
3775	/// Tests `extend` on an empty vector.
3776	#[test]
3777	fn extend_empty() {
3778		use crate::classes::extend::extend;
3779		let result =
3780			extend::<VecBrand, _, _>(|v: Vec<i32>| v.iter().sum::<i32>(), Vec::<i32>::new());
3781		assert_eq!(result, Vec::<i32>::new());
3782	}
3783
3784	/// Tests `extend` on a singleton vector.
3785	#[test]
3786	fn extend_singleton() {
3787		use crate::classes::extend::extend;
3788		let result = extend::<VecBrand, _, _>(|v: Vec<i32>| v.iter().sum::<i32>(), vec![42]);
3789		assert_eq!(result, vec![42]);
3790	}
3791
3792	// -- Ref trait laws --
3793
3794	/// Tests the identity law for RefFunctor: ref_map(deref, v) == v.
3795	#[quickcheck]
3796	fn ref_functor_identity(v: Vec<i32>) -> bool {
3797		use crate::classes::ref_functor::RefFunctor;
3798		VecBrand::ref_map(|x: &i32| *x, &v) == v
3799	}
3800
3801	/// Tests the composition law for RefFunctor:
3802	/// ref_map(|x| g(&f(x)), v) == ref_map(g, ref_map(f, v)).
3803	#[quickcheck]
3804	fn ref_functor_composition(v: Vec<i32>) -> bool {
3805		use crate::classes::ref_functor::RefFunctor;
3806		let f = |x: &i32| x.wrapping_add(1);
3807		let g = |x: &i32| x.wrapping_mul(2);
3808		VecBrand::ref_map(|x: &i32| g(&f(x)), &v) == VecBrand::ref_map(g, &VecBrand::ref_map(f, &v))
3809	}
3810
3811	/// Tests RefFoldable with Additive monoid: ref_fold_map matches iter().sum().
3812	#[quickcheck]
3813	fn ref_foldable_additive(v: Vec<i32>) -> bool {
3814		use crate::{
3815			brands::RcFnBrand,
3816			classes::ref_foldable::RefFoldable,
3817			types::Additive,
3818		};
3819		let result: Additive<i32> =
3820			VecBrand::ref_fold_map::<RcFnBrand, _, _>(|x: &i32| Additive(*x), &v);
3821		result.0 == v.iter().copied().fold(0i32, |a, b| a.wrapping_add(b))
3822	}
3823
3824	/// Tests the left identity law for RefSemimonad:
3825	/// ref_bind(vec![x], |a| vec![*a]) == vec![x].
3826	#[quickcheck]
3827	fn ref_semimonad_left_identity(x: i32) -> bool {
3828		use crate::classes::ref_semimonad::RefSemimonad;
3829		VecBrand::ref_bind(&vec![x], |a: &i32| vec![*a]) == vec![x]
3830	}
3831
3832	/// Tests the associativity law for RefSemimonad:
3833	/// ref_bind(ref_bind(v, f), g) == ref_bind(v, |a| ref_bind(f(a), g)).
3834	#[quickcheck]
3835	fn ref_semimonad_associativity(v: Vec<i32>) -> bool {
3836		use crate::classes::ref_semimonad::RefSemimonad;
3837		let f = |a: &i32| vec![a.wrapping_add(1), a.wrapping_mul(2)];
3838		let g = |b: &i32| vec![b.wrapping_add(10)];
3839		let lhs = VecBrand::ref_bind(&VecBrand::ref_bind(&v, f), g);
3840		let rhs = VecBrand::ref_bind(&v, |a: &i32| VecBrand::ref_bind(&f(a), g));
3841		lhs == rhs
3842	}
3843
3844	/// Tests ParRefFunctor equivalence: par_ref_map(f, v) == ref_map(f, v).
3845	#[quickcheck]
3846	fn par_ref_functor_equivalence(v: Vec<i32>) -> bool {
3847		use crate::classes::{
3848			par_ref_functor::ParRefFunctor,
3849			ref_functor::RefFunctor,
3850		};
3851		let f = |x: &i32| x.wrapping_mul(3).wrapping_add(7);
3852		VecBrand::par_ref_map(f, &v) == VecBrand::ref_map(f, &v)
3853	}
3854
3855	// RefSemimonad Laws (continued)
3856
3857	/// Tests the right identity law for RefSemimonad:
3858	/// `ref_bind(v, |a| ref_pure(a)) == v`.
3859	#[quickcheck]
3860	fn ref_semimonad_right_identity(v: Vec<i32>) -> bool {
3861		use crate::classes::{
3862			ref_pointed::RefPointed,
3863			ref_semimonad::RefSemimonad,
3864		};
3865		VecBrand::ref_bind(&v, |a: &i32| VecBrand::ref_pure(a)) == v
3866	}
3867
3868	// RefLift Laws
3869
3870	/// Tests the identity law for RefLift:
3871	/// `ref_lift2(|_, b| *b, pure(unit), fa) == fa`.
3872	#[quickcheck]
3873	fn ref_lift_identity(v: Vec<i32>) -> bool {
3874		use crate::classes::ref_lift::RefLift;
3875		VecBrand::ref_lift2(|_: &(), b: &i32| *b, &vec![()], &v) == v
3876	}
3877
3878	// RefTraversable Laws
3879
3880	/// Tests the identity law for RefTraversable:
3881	/// `ref_traverse(|a| Identity(*a), ta) == Identity(ta)`.
3882	#[quickcheck]
3883	fn ref_traversable_identity(v: Vec<i32>) -> bool {
3884		use crate::{
3885			classes::ref_traversable::RefTraversable,
3886			types::Identity,
3887		};
3888		let result: Identity<Vec<i32>> =
3889			VecBrand::ref_traverse::<RcFnBrand, _, _, IdentityBrand>(|a: &i32| Identity(*a), &v);
3890		result == Identity(v)
3891	}
3892
3893	/// Tests RefTraversable naturality: ref_traverse(f, ta) produces
3894	/// the same result as traverse(|a| f(&a), ta).
3895	#[quickcheck]
3896	fn ref_traversable_consistent_with_traverse(v: Vec<i32>) -> bool {
3897		use crate::classes::{
3898			ref_traversable::RefTraversable,
3899			traversable::Traversable,
3900		};
3901		let ref_result: Option<Vec<String>> = VecBrand::ref_traverse::<RcFnBrand, _, _, OptionBrand>(
3902			|a: &i32| Some(a.to_string()),
3903			&v,
3904		);
3905		let val_result: Option<Vec<String>> =
3906			VecBrand::traverse::<i32, String, OptionBrand>(|a: i32| Some(a.to_string()), v);
3907		ref_result == val_result
3908	}
3909
3910	// RefCompactable Laws
3911
3912	/// RefCompactable identity: ref_compact of ref_map(Some, &v) preserves values
3913	#[quickcheck]
3914	fn ref_compactable_identity(v: Vec<i32>) -> bool {
3915		let mapped: Vec<Option<i32>> = v.iter().map(|a| Some(*a)).collect();
3916		explicit::compact::<VecBrand, _, _, _>(&mapped) == v
3917	}
3918
3919	// RefAlt Laws
3920
3921	/// RefAlt associativity
3922	#[quickcheck]
3923	fn ref_alt_associativity(
3924		x: Vec<i32>,
3925		y: Vec<i32>,
3926		z: Vec<i32>,
3927	) -> bool {
3928		explicit::alt::<VecBrand, _, _, _>(&explicit::alt::<VecBrand, _, _, _>(&x, &y), &z)
3929			== explicit::alt::<VecBrand, _, _, _>(&x, &explicit::alt::<VecBrand, _, _, _>(&y, &z))
3930	}
3931
3932	/// RefAlt distributivity with RefFunctor
3933	#[quickcheck]
3934	fn ref_alt_distributivity(
3935		x: Vec<i32>,
3936		y: Vec<i32>,
3937	) -> bool {
3938		let f = |a: &i32| a.wrapping_mul(2);
3939		explicit::map::<VecBrand, _, _, _, _>(f, &explicit::alt::<VecBrand, _, _, _>(&x, &y))
3940			== explicit::alt::<VecBrand, _, _, _>(
3941				&explicit::map::<VecBrand, _, _, _, _>(f, &x),
3942				&explicit::map::<VecBrand, _, _, _, _>(f, &y),
3943			)
3944	}
3945}