Skip to main content

fp_library/types/
vec.rs

1//! Functional programming trait implementations for the standard library [`Vec`] type.
2//!
3//! Extends `Vec` with [`Functor`](crate::classes::Functor), [`Monad`](crate::classes::semimonad::Semimonad), [`Foldable`](crate::classes::Foldable), [`Traversable`](crate::classes::Traversable), [`Extend`](crate::classes::Extend), [`Filterable`](crate::classes::Filterable), [`Witherable`](crate::classes::Witherable), and parallel folding instances.
4
5#[fp_macros::document_module]
6mod inner {
7	use {
8		crate::{
9			Apply,
10			brands::{
11				OptionBrand,
12				VecBrand,
13			},
14			classes::*,
15			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::<RcFnBrand, VecBrand, _, _>(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::<RcFnBrand, VecBrand, _, _>(
3055			pure::<VecBrand, _>(<RcFnBrand as LiftFn>::new(identity)),
3056			v.clone(),
3057		) == v
3058	}
3059
3060	/// Tests the homomorphism law for Applicative.
3061	#[quickcheck]
3062	fn applicative_homomorphism(x: i32) -> bool {
3063		let f = |x: i32| x.wrapping_mul(2);
3064		apply::<RcFnBrand, VecBrand, _, _>(
3065			pure::<VecBrand, _>(<RcFnBrand as LiftFn>::new(f)),
3066			pure::<VecBrand, _>(x),
3067		) == pure::<VecBrand, _>(f(x))
3068	}
3069
3070	/// Tests the composition law for Applicative.
3071	#[quickcheck]
3072	fn applicative_composition(
3073		w: Vec<i32>,
3074		u_seeds: Vec<i32>,
3075		v_seeds: Vec<i32>,
3076	) -> bool {
3077		let u_fns: Vec<_> = u_seeds
3078			.iter()
3079			.map(|&i| <RcFnBrand as LiftFn>::new(move |x: i32| x.wrapping_add(i)))
3080			.collect();
3081		let v_fns: Vec<_> = v_seeds
3082			.iter()
3083			.map(|&i| <RcFnBrand as LiftFn>::new(move |x: i32| x.wrapping_mul(i)))
3084			.collect();
3085
3086		// RHS: u <*> (v <*> w)
3087		let vw = apply::<RcFnBrand, VecBrand, _, _>(v_fns.clone(), w.clone());
3088		let rhs = apply::<RcFnBrand, VecBrand, _, _>(u_fns.clone(), vw);
3089
3090		// LHS: pure(compose) <*> u <*> v <*> w
3091		// equivalent to (u . v) <*> w
3092		// We construct (u . v) manually as the cartesian product of compositions
3093		let uv_fns: Vec<_> = u_fns
3094			.iter()
3095			.flat_map(|uf| {
3096				v_fns.iter().map(move |vf| {
3097					let uf = uf.clone();
3098					let vf = vf.clone();
3099					<RcFnBrand as LiftFn>::new(move |x| uf(vf(x)))
3100				})
3101			})
3102			.collect();
3103
3104		let lhs = apply::<RcFnBrand, VecBrand, _, _>(uv_fns, w);
3105
3106		lhs == rhs
3107	}
3108
3109	/// Tests the interchange law for Applicative.
3110	#[quickcheck]
3111	fn applicative_interchange(y: i32) -> bool {
3112		// u <*> pure y = pure ($ y) <*> u
3113		let f = |x: i32| x.wrapping_mul(2);
3114		let u = vec![<RcFnBrand as LiftFn>::new(f)];
3115
3116		let lhs = apply::<RcFnBrand, VecBrand, _, _>(u.clone(), pure::<VecBrand, _>(y));
3117
3118		let rhs_fn = <RcFnBrand as LiftFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
3119		let rhs = apply::<RcFnBrand, VecBrand, _, _>(pure::<VecBrand, _>(rhs_fn), u);
3120
3121		lhs == rhs
3122	}
3123
3124	// Semigroup Laws
3125
3126	/// Tests the associativity law for Semigroup.
3127	#[quickcheck]
3128	fn semigroup_associativity(
3129		a: Vec<i32>,
3130		b: Vec<i32>,
3131		c: Vec<i32>,
3132	) -> bool {
3133		append(a.clone(), append(b.clone(), c.clone())) == append(append(a, b), c)
3134	}
3135
3136	// Monoid Laws
3137
3138	/// Tests the left identity law for Monoid.
3139	#[quickcheck]
3140	fn monoid_left_identity(a: Vec<i32>) -> bool {
3141		append(empty::<Vec<i32>>(), a.clone()) == a
3142	}
3143
3144	/// Tests the right identity law for Monoid.
3145	#[quickcheck]
3146	fn monoid_right_identity(a: Vec<i32>) -> bool {
3147		append(a.clone(), empty::<Vec<i32>>()) == a
3148	}
3149
3150	// Monad Laws
3151
3152	/// Tests the left identity law for Monad.
3153	#[quickcheck]
3154	fn monad_left_identity(a: i32) -> bool {
3155		let f = |x: i32| vec![x.wrapping_mul(2)];
3156		explicit::bind::<VecBrand, _, _, _, _>(pure::<VecBrand, _>(a), f) == f(a)
3157	}
3158
3159	/// Tests the right identity law for Monad.
3160	#[quickcheck]
3161	fn monad_right_identity(m: Vec<i32>) -> bool {
3162		explicit::bind::<VecBrand, _, _, _, _>(m.clone(), pure::<VecBrand, _>) == m
3163	}
3164
3165	/// Tests the associativity law for Monad.
3166	#[quickcheck]
3167	fn monad_associativity(m: Vec<i32>) -> bool {
3168		let f = |x: i32| vec![x.wrapping_mul(2)];
3169		let g = |x: i32| vec![x.wrapping_add(1)];
3170		explicit::bind::<VecBrand, _, _, _, _>(
3171			explicit::bind::<VecBrand, _, _, _, _>(m.clone(), f),
3172			g,
3173		) == explicit::bind::<VecBrand, _, _, _, _>(m, |x| {
3174			explicit::bind::<VecBrand, _, _, _, _>(f(x), g)
3175		})
3176	}
3177
3178	// Edge Cases
3179
3180	/// Tests `map` on an empty vector.
3181	#[test]
3182	fn map_empty() {
3183		assert_eq!(
3184			explicit::map::<VecBrand, _, _, _, _>(|x: i32| x + 1, vec![] as Vec<i32>),
3185			vec![] as Vec<i32>
3186		);
3187	}
3188
3189	/// Tests `bind` on an empty vector.
3190	#[test]
3191	fn bind_empty() {
3192		assert_eq!(
3193			explicit::bind::<VecBrand, _, _, _, _>(vec![] as Vec<i32>, |x: i32| vec![x + 1]),
3194			vec![] as Vec<i32>
3195		);
3196	}
3197
3198	/// Tests `bind` returning an empty vector.
3199	#[test]
3200	fn bind_returning_empty() {
3201		assert_eq!(
3202			explicit::bind::<VecBrand, _, _, _, _>(vec![1, 2, 3], |_| vec![] as Vec<i32>),
3203			vec![] as Vec<i32>
3204		);
3205	}
3206
3207	/// Tests `fold_right` on an empty vector.
3208	#[test]
3209	fn fold_right_empty() {
3210		assert_eq!(
3211			crate::functions::explicit::fold_right::<RcFnBrand, VecBrand, _, _, _, _>(
3212				|x: i32, acc| x + acc,
3213				0,
3214				vec![]
3215			),
3216			0
3217		);
3218	}
3219
3220	/// Tests `fold_left` on an empty vector.
3221	#[test]
3222	fn fold_left_empty() {
3223		assert_eq!(
3224			crate::functions::explicit::fold_left::<RcFnBrand, VecBrand, _, _, _, _>(
3225				|acc, x: i32| acc + x,
3226				0,
3227				vec![]
3228			),
3229			0
3230		);
3231	}
3232
3233	/// Tests `traverse` on an empty vector.
3234	#[test]
3235	fn traverse_empty() {
3236		use crate::brands::OptionBrand;
3237		assert_eq!(
3238			crate::classes::traversable::traverse::<VecBrand, _, _, OptionBrand>(
3239				|x: i32| Some(x + 1),
3240				vec![]
3241			),
3242			Some(vec![])
3243		);
3244	}
3245
3246	/// Tests `traverse` returning an empty vector.
3247	#[test]
3248	fn traverse_returning_empty() {
3249		use crate::brands::OptionBrand;
3250		assert_eq!(
3251			crate::classes::traversable::traverse::<VecBrand, _, _, OptionBrand>(
3252				|_: i32| None::<i32>,
3253				vec![1, 2, 3]
3254			),
3255			None
3256		);
3257	}
3258
3259	/// Tests `construct` with an empty tail.
3260	#[test]
3261	fn construct_empty_tail() {
3262		assert_eq!(VecBrand::construct(1, vec![]), vec![1]);
3263	}
3264
3265	/// Tests `deconstruct` on an empty slice.
3266	#[test]
3267	fn deconstruct_empty() {
3268		assert_eq!(VecBrand::deconstruct::<i32>(&[]), None);
3269	}
3270
3271	// Parallel Trait Tests
3272
3273	/// Tests `par_map` on a vector.
3274	#[test]
3275	fn par_map_basic() {
3276		let v = vec![1, 2, 3];
3277		let result: Vec<i32> = par_map::<VecBrand, _, _>(|x: i32| x * 2, v);
3278		assert_eq!(result, vec![2, 4, 6]);
3279	}
3280
3281	/// Tests `par_filter` on a vector.
3282	#[test]
3283	fn par_filter_basic() {
3284		let v = vec![1, 2, 3, 4, 5];
3285		let result: Vec<i32> = par_filter::<VecBrand, _>(|x: &i32| x % 2 == 0, v);
3286		assert_eq!(result, vec![2, 4]);
3287	}
3288
3289	/// Tests `par_filter_map` on a vector.
3290	#[test]
3291	fn par_filter_map_basic() {
3292		let v = vec![1, 2, 3, 4, 5];
3293		let result: Vec<i32> = par_filter_map::<VecBrand, _, _>(
3294			|x: i32| if x % 2 == 0 { Some(x * 10) } else { None },
3295			v,
3296		);
3297		assert_eq!(result, vec![20, 40]);
3298	}
3299
3300	/// Tests `par_compact` on a vector of options.
3301	#[test]
3302	fn par_compact_basic() {
3303		let v = vec![Some(1), None, Some(3), None, Some(5)];
3304		let result: Vec<i32> = par_compact::<VecBrand, _>(v);
3305		assert_eq!(result, vec![1, 3, 5]);
3306	}
3307
3308	/// Tests `par_separate` on a vector of results.
3309	#[test]
3310	fn par_separate_basic() {
3311		let v: Vec<Result<i32, &str>> = vec![Ok(1), Err("a"), Ok(3), Err("b")];
3312		let (errs, oks): (Vec<&str>, Vec<i32>) = par_separate::<VecBrand, _, _>(v);
3313		assert_eq!(errs, vec!["a", "b"]);
3314		assert_eq!(oks, vec![1, 3]);
3315	}
3316
3317	/// Tests `par_map_with_index` on a vector.
3318	#[test]
3319	fn par_map_with_index_basic() {
3320		let v = vec![10, 20, 30];
3321		let result: Vec<i32> = par_map_with_index::<VecBrand, _, _>(|i, x: i32| x + i as i32, v);
3322		assert_eq!(result, vec![10, 21, 32]);
3323	}
3324
3325	/// Tests `par_fold_map` on an empty vector.
3326	#[test]
3327	fn par_fold_map_empty() {
3328		let v: Vec<i32> = vec![];
3329		assert_eq!(par_fold_map::<VecBrand, _, _>(|x: i32| x.to_string(), v), "".to_string());
3330	}
3331
3332	/// Tests `par_fold_map` on multiple elements.
3333	#[test]
3334	fn par_fold_map_multiple() {
3335		let v = vec![1, 2, 3];
3336		assert_eq!(par_fold_map::<VecBrand, _, _>(|x: i32| x.to_string(), v), "123".to_string());
3337	}
3338
3339	/// Tests `par_fold_map_with_index` on a vector.
3340	#[test]
3341	fn par_fold_map_with_index_basic() {
3342		let v = vec![10, 20, 30];
3343		let result: String =
3344			par_fold_map_with_index::<VecBrand, _, _>(|i, x: i32| format!("{i}:{x}"), v);
3345		assert_eq!(result, "0:101:202:30");
3346	}
3347
3348	// Filterable Laws
3349
3350	/// Tests `filterMap identity ≡ compact`.
3351	#[quickcheck]
3352	fn filterable_filter_map_identity(x: Vec<Option<i32>>) -> bool {
3353		explicit::filter_map::<VecBrand, _, _, _, _>(identity, x.clone())
3354			== explicit::compact::<VecBrand, _, _, _>(x)
3355	}
3356
3357	/// Tests `filterMap Just ≡ identity`.
3358	#[quickcheck]
3359	fn filterable_filter_map_just(x: Vec<i32>) -> bool {
3360		explicit::filter_map::<VecBrand, _, _, _, _>(Some, x.clone()) == x
3361	}
3362
3363	/// Tests `filterMap (l <=< r) ≡ filterMap l <<< filterMap r`.
3364	#[quickcheck]
3365	fn filterable_filter_map_composition(x: Vec<i32>) -> bool {
3366		let r = |i: i32| if i % 2 == 0 { Some(i) } else { None };
3367		let l = |i: i32| if i > 5 { Some(i) } else { None };
3368		let composed = |i| explicit::bind::<OptionBrand, _, _, _, _>(r(i), l);
3369
3370		explicit::filter_map::<VecBrand, _, _, _, _>(composed, x.clone())
3371			== explicit::filter_map::<VecBrand, _, _, _, _>(
3372				l,
3373				explicit::filter_map::<VecBrand, _, _, _, _>(r, x),
3374			)
3375	}
3376
3377	/// Tests `filter ≡ filterMap <<< maybeBool`.
3378	#[quickcheck]
3379	fn filterable_filter_consistency(x: Vec<i32>) -> bool {
3380		let p = |i: i32| i % 2 == 0;
3381		let maybe_bool = |i| if p(i) { Some(i) } else { None };
3382
3383		explicit::filter::<VecBrand, _, _, _>(p, x.clone())
3384			== explicit::filter_map::<VecBrand, _, _, _, _>(maybe_bool, x)
3385	}
3386
3387	/// Tests `partitionMap identity ≡ separate`.
3388	#[quickcheck]
3389	fn filterable_partition_map_identity(x: Vec<Result<i32, i32>>) -> bool {
3390		explicit::partition_map::<VecBrand, _, _, _, _, _>(identity, x.clone())
3391			== explicit::separate::<VecBrand, _, _, _, _>(x)
3392	}
3393
3394	/// Tests `partitionMap Right ≡ identity` (on the right side).
3395	#[quickcheck]
3396	fn filterable_partition_map_right_identity(x: Vec<i32>) -> bool {
3397		let (_, oks) = explicit::partition_map::<VecBrand, _, _, _, _, _>(Ok::<_, i32>, x.clone());
3398		oks == x
3399	}
3400
3401	/// Tests `partitionMap Left ≡ identity` (on the left side).
3402	#[quickcheck]
3403	fn filterable_partition_map_left_identity(x: Vec<i32>) -> bool {
3404		let (errs, _) =
3405			explicit::partition_map::<VecBrand, _, _, _, _, _>(Err::<i32, _>, x.clone());
3406		errs == x
3407	}
3408
3409	/// Tests `f <<< partition ≡ partitionMap <<< eitherBool`.
3410	#[quickcheck]
3411	fn filterable_partition_consistency(x: Vec<i32>) -> bool {
3412		let p = |i: i32| i % 2 == 0;
3413		let either_bool = |i| if p(i) { Ok(i) } else { Err(i) };
3414
3415		let (not_satisfied, satisfied) = explicit::partition::<VecBrand, _, _, _>(p, x.clone());
3416		let (errs, oks) = explicit::partition_map::<VecBrand, _, _, _, _, _>(either_bool, x);
3417
3418		satisfied == oks && not_satisfied == errs
3419	}
3420
3421	// Witherable Laws
3422
3423	/// Tests `wither (pure <<< Just) ≡ pure`.
3424	#[quickcheck]
3425	fn witherable_identity(x: Vec<i32>) -> bool {
3426		explicit::wither::<RcFnBrand, VecBrand, OptionBrand, _, _, _, _>(
3427			|i| Some(Some(i)),
3428			x.clone(),
3429		) == Some(x)
3430	}
3431
3432	/// Tests `wilt p ≡ map separate <<< traverse p`.
3433	#[quickcheck]
3434	fn witherable_wilt_consistency(x: Vec<i32>) -> bool {
3435		let p = |i: i32| Some(if i % 2 == 0 { Ok(i) } else { Err(i) });
3436
3437		let lhs = explicit::wilt::<RcFnBrand, VecBrand, OptionBrand, _, _, _, _, _>(p, x.clone());
3438		let rhs = crate::dispatch::functor::explicit::map::<OptionBrand, _, _, _, _>(
3439			explicit::separate::<VecBrand, _, _, _, _>,
3440			explicit::traverse::<RcFnBrand, VecBrand, _, _, OptionBrand, _, _>(p, x),
3441		);
3442
3443		lhs == rhs
3444	}
3445
3446	/// Tests `wither p ≡ map compact <<< traverse p`.
3447	#[quickcheck]
3448	fn witherable_wither_consistency(x: Vec<i32>) -> bool {
3449		let p = |i: i32| Some(if i % 2 == 0 { Some(i) } else { None });
3450
3451		let lhs = explicit::wither::<RcFnBrand, VecBrand, OptionBrand, _, _, _, _>(p, x.clone());
3452		let rhs = crate::dispatch::functor::explicit::map::<OptionBrand, _, _, _, _>(
3453			explicit::compact::<VecBrand, _, _, _>,
3454			explicit::traverse::<RcFnBrand, VecBrand, _, _, OptionBrand, _, _>(p, x),
3455		);
3456
3457		lhs == rhs
3458	}
3459
3460	// Alt Laws
3461
3462	/// Tests the associativity law for Alt.
3463	#[quickcheck]
3464	fn alt_associativity(
3465		x: Vec<i32>,
3466		y: Vec<i32>,
3467		z: Vec<i32>,
3468	) -> bool {
3469		explicit::alt::<VecBrand, _, _, _>(
3470			explicit::alt::<VecBrand, _, _, _>(x.clone(), y.clone()),
3471			z.clone(),
3472		) == explicit::alt::<VecBrand, _, _, _>(x, explicit::alt::<VecBrand, _, _, _>(y, z))
3473	}
3474
3475	/// Tests the distributivity law for Alt.
3476	#[quickcheck]
3477	fn alt_distributivity(
3478		x: Vec<i32>,
3479		y: Vec<i32>,
3480	) -> bool {
3481		let f = |i: i32| i.wrapping_mul(2).wrapping_add(1);
3482		explicit::map::<VecBrand, _, _, _, _>(
3483			f,
3484			explicit::alt::<VecBrand, _, _, _>(x.clone(), y.clone()),
3485		) == explicit::alt::<VecBrand, _, _, _>(
3486			explicit::map::<VecBrand, _, _, _, _>(f, x),
3487			explicit::map::<VecBrand, _, _, _, _>(f, y),
3488		)
3489	}
3490
3491	// Plus Laws
3492
3493	/// Tests the left identity law for Plus.
3494	#[quickcheck]
3495	fn plus_left_identity(x: Vec<i32>) -> bool {
3496		explicit::alt::<VecBrand, _, _, _>(plus_empty::<VecBrand, i32>(), x.clone()) == x
3497	}
3498
3499	/// Tests the right identity law for Plus.
3500	#[quickcheck]
3501	fn plus_right_identity(x: Vec<i32>) -> bool {
3502		explicit::alt::<VecBrand, _, _, _>(x.clone(), plus_empty::<VecBrand, i32>()) == x
3503	}
3504
3505	/// Tests the annihilation law for Plus.
3506	#[test]
3507	fn plus_annihilation() {
3508		let f = |i: i32| i.wrapping_mul(2);
3509		assert_eq!(
3510			explicit::map::<VecBrand, _, _, _, _>(f, plus_empty::<VecBrand, i32>()),
3511			plus_empty::<VecBrand, i32>(),
3512		);
3513	}
3514
3515	// Compactable Laws (Plus-dependent)
3516
3517	/// Tests the functor identity law for Compactable.
3518	#[quickcheck]
3519	fn compactable_functor_identity(fa: Vec<i32>) -> bool {
3520		explicit::compact::<VecBrand, _, _, _>(explicit::map::<VecBrand, _, _, _, _>(
3521			Some,
3522			fa.clone(),
3523		)) == fa
3524	}
3525
3526	/// Tests the Plus annihilation (empty) law for Compactable.
3527	#[test]
3528	fn compactable_plus_annihilation_empty() {
3529		assert_eq!(
3530			explicit::compact::<VecBrand, _, _, _>(plus_empty::<VecBrand, Option<i32>>()),
3531			plus_empty::<VecBrand, i32>(),
3532		);
3533	}
3534
3535	/// Tests the Plus annihilation (map) law for Compactable.
3536	#[quickcheck]
3537	fn compactable_plus_annihilation_map(xs: Vec<i32>) -> bool {
3538		explicit::compact::<VecBrand, _, _, _>(explicit::map::<VecBrand, _, _, _, _>(
3539			|_: i32| None::<i32>,
3540			xs,
3541		)) == plus_empty::<VecBrand, i32>()
3542	}
3543
3544	// Edge Cases
3545
3546	/// Tests `compact` on an empty vector.
3547	#[test]
3548	fn compact_empty() {
3549		assert_eq!(
3550			explicit::compact::<VecBrand, i32, _, _>(vec![] as Vec<Option<i32>>),
3551			vec![] as Vec<i32>
3552		);
3553	}
3554
3555	/// Tests `compact` on a vector with `None`.
3556	#[test]
3557	fn compact_with_none() {
3558		assert_eq!(
3559			explicit::compact::<VecBrand, i32, _, _>(vec![Some(1), None, Some(2)]),
3560			vec![1, 2]
3561		);
3562	}
3563
3564	/// Tests `separate` on an empty vector.
3565	#[test]
3566	fn separate_empty() {
3567		let (errs, oks) =
3568			explicit::separate::<VecBrand, i32, i32, _, _>(vec![] as Vec<Result<i32, i32>>);
3569		assert_eq!(oks, vec![] as Vec<i32>);
3570		assert_eq!(errs, vec![] as Vec<i32>);
3571	}
3572
3573	/// Tests `separate` on a vector with `Ok` and `Err`.
3574	#[test]
3575	fn separate_mixed() {
3576		let (errs, oks) =
3577			explicit::separate::<VecBrand, i32, i32, _, _>(vec![Ok(1), Err(2), Ok(3)]);
3578		assert_eq!(oks, vec![1, 3]);
3579		assert_eq!(errs, vec![2]);
3580	}
3581
3582	/// Tests `partition_map` on an empty vector.
3583	#[test]
3584	fn partition_map_empty() {
3585		let (errs, oks) =
3586			explicit::partition_map::<VecBrand, _, _, _, _, _>(|x: i32| Ok::<i32, i32>(x), vec![]);
3587		assert_eq!(oks, vec![] as Vec<i32>);
3588		assert_eq!(errs, vec![] as Vec<i32>);
3589	}
3590
3591	/// Tests `partition` on an empty vector.
3592	#[test]
3593	fn partition_empty() {
3594		let (not_satisfied, satisfied) =
3595			explicit::partition::<VecBrand, _, _, _>(|x: i32| x > 0, vec![]);
3596		assert_eq!(satisfied, vec![] as Vec<i32>);
3597		assert_eq!(not_satisfied, vec![] as Vec<i32>);
3598	}
3599
3600	/// Tests `filter_map` on an empty vector.
3601	#[test]
3602	fn filter_map_empty() {
3603		assert_eq!(
3604			explicit::filter_map::<VecBrand, i32, _, _, _>(|x: i32| Some(x), vec![]),
3605			vec![] as Vec<i32>
3606		);
3607	}
3608
3609	/// Tests `filter` on an empty vector.
3610	#[test]
3611	fn filter_empty() {
3612		assert_eq!(
3613			explicit::filter::<VecBrand, _, _, _>(|x: i32| x > 0, vec![]),
3614			vec![] as Vec<i32>
3615		);
3616	}
3617
3618	/// Tests `wilt` on an empty vector.
3619	#[test]
3620	fn wilt_empty() {
3621		let res = explicit::wilt::<RcFnBrand, VecBrand, OptionBrand, _, _, _, _, _>(
3622			|x: i32| Some(Ok::<i32, i32>(x)),
3623			vec![],
3624		);
3625		assert_eq!(res, Some((vec![], vec![])));
3626	}
3627
3628	/// Tests `wither` on an empty vector.
3629	#[test]
3630	fn wither_empty() {
3631		let res = explicit::wither::<RcFnBrand, VecBrand, OptionBrand, _, _, _, _>(
3632			|x: i32| Some(Some(x)),
3633			vec![],
3634		);
3635		assert_eq!(res, Some(vec![]));
3636	}
3637
3638	// Parallel Trait Laws
3639
3640	/// Verifies that `par_fold_map` correctly sums a large vector (100,000 elements).
3641	#[test]
3642	fn test_large_vector_par_fold_map() {
3643		use crate::types::Additive;
3644
3645		let xs: Vec<i32> = (0 .. 100000).collect();
3646		let res = par_fold_map::<VecBrand, _, _>(|x: i32| Additive(x as i64), xs);
3647		assert_eq!(res, Additive(4999950000));
3648	}
3649
3650	/// Property: `par_map` agrees with sequential `map`.
3651	#[quickcheck]
3652	fn prop_par_map_equals_map(xs: Vec<i32>) -> bool {
3653		let f = |x: i32| x.wrapping_add(1);
3654		let seq_res = explicit::map::<VecBrand, _, _, _, _>(f, xs.clone());
3655		let par_res = par_map::<VecBrand, _, _>(f, xs);
3656		seq_res == par_res
3657	}
3658
3659	/// Property: `par_fold_map` agrees with sequential `fold_map`.
3660	#[quickcheck]
3661	fn prop_par_fold_map_equals_fold_map(xs: Vec<i32>) -> bool {
3662		use crate::types::Additive;
3663
3664		let f = |x: i32| Additive(x as i64);
3665		let seq_res =
3666			crate::functions::explicit::fold_map::<crate::brands::RcFnBrand, VecBrand, _, _, _, _>(
3667				f,
3668				xs.clone(),
3669			);
3670		let par_res = par_fold_map::<VecBrand, _, _>(f, xs);
3671		seq_res == par_res
3672	}
3673
3674	/// Property: `par_fold_map` on an empty vector returns the Monoid's empty value.
3675	#[quickcheck]
3676	fn prop_par_fold_map_empty_is_empty(xs: Vec<i32>) -> bool {
3677		use crate::types::Additive;
3678
3679		if !xs.is_empty() {
3680			return true;
3681		}
3682		let par_res = par_fold_map::<VecBrand, _, _>(|x: i32| Additive(x as i64), xs);
3683		par_res == empty::<Additive<i64>>()
3684	}
3685
3686	// MonadRec tests
3687
3688	/// Tests the MonadRec identity law: `tail_rec_m(|a| pure(Done(a)), x) == pure(x)`.
3689	#[quickcheck]
3690	fn monad_rec_identity(x: i32) -> bool {
3691		use {
3692			crate::classes::monad_rec::tail_rec_m,
3693			core::ops::ControlFlow,
3694		};
3695		tail_rec_m::<VecBrand, _, _>(|a| vec![ControlFlow::Break(a)], x) == vec![x]
3696	}
3697
3698	/// Tests a simple linear recursion via `tail_rec_m`.
3699	#[test]
3700	fn monad_rec_linear() {
3701		use {
3702			crate::classes::monad_rec::tail_rec_m,
3703			core::ops::ControlFlow,
3704		};
3705		// Count up to 5
3706		let result = tail_rec_m::<VecBrand, _, _>(
3707			|n| {
3708				if n < 5 { vec![ControlFlow::Continue(n + 1)] } else { vec![ControlFlow::Break(n)] }
3709			},
3710			0,
3711		);
3712		assert_eq!(result, vec![5]);
3713	}
3714
3715	/// Tests branching nondeterminism via `tail_rec_m`.
3716	#[test]
3717	fn monad_rec_branching() {
3718		use {
3719			crate::classes::monad_rec::tail_rec_m,
3720			core::ops::ControlFlow,
3721		};
3722		// Each step either finishes or continues
3723		let result = tail_rec_m::<VecBrand, _, _>(
3724			|n: i32| {
3725				if n < 2 {
3726					vec![ControlFlow::Continue(n + 1), ControlFlow::Break(n * 100)]
3727				} else {
3728					vec![ControlFlow::Break(n * 100)]
3729				}
3730			},
3731			0,
3732		);
3733		// n=0: Loop(1), Done(0)
3734		// n=1: Loop(2), Done(100)
3735		// n=2: Done(200)
3736		assert_eq!(result, vec![0, 100, 200]);
3737	}
3738
3739	/// Tests that `tail_rec_m` handles an empty result from the step function.
3740	#[test]
3741	fn monad_rec_empty() {
3742		use {
3743			crate::classes::monad_rec::tail_rec_m,
3744			core::ops::ControlFlow,
3745		};
3746		let result: Vec<i32> =
3747			tail_rec_m::<VecBrand, _, _>(|_n| Vec::<ControlFlow<i32, i32>>::new(), 0);
3748		assert_eq!(result, Vec::<i32>::new());
3749	}
3750
3751	// Extend Laws
3752
3753	/// Tests basic `extend` on `Vec`: sum of suffixes.
3754	#[test]
3755	fn extend_sum_of_suffixes() {
3756		use crate::classes::extend::extend;
3757		let result = extend::<VecBrand, _, _>(|v: Vec<i32>| v.iter().sum::<i32>(), vec![1, 2, 3]);
3758		assert_eq!(result, vec![6, 5, 3]);
3759	}
3760
3761	/// Extend associativity: `extend(f, extend(g, w)) == extend(|w| f(extend(g, w)), w)`.
3762	#[quickcheck]
3763	fn extend_associativity(w: Vec<i32>) -> bool {
3764		use crate::classes::extend::extend;
3765		let g = |v: Vec<i32>| v.iter().fold(0i32, |a, b| a.wrapping_mul(2).wrapping_add(*b));
3766		let f = |v: Vec<i32>| v.iter().fold(0i32, |a, b| a.wrapping_add(b.wrapping_add(1)));
3767		let lhs = extend::<VecBrand, _, _>(f, extend::<VecBrand, _, _>(g, w.clone()));
3768		let rhs = extend::<VecBrand, _, _>(|w: Vec<i32>| f(extend::<VecBrand, _, _>(g, w)), w);
3769		lhs == rhs
3770	}
3771
3772	/// Tests that `duplicate` produces suffixes.
3773	#[test]
3774	fn extend_duplicate_suffixes() {
3775		use crate::classes::extend::duplicate;
3776		let result = duplicate::<VecBrand, _>(vec![1, 2, 3]);
3777		assert_eq!(result, vec![vec![1, 2, 3], vec![2, 3], vec![3]]);
3778	}
3779
3780	/// Tests `extend` on an empty vector.
3781	#[test]
3782	fn extend_empty() {
3783		use crate::classes::extend::extend;
3784		let result =
3785			extend::<VecBrand, _, _>(|v: Vec<i32>| v.iter().sum::<i32>(), Vec::<i32>::new());
3786		assert_eq!(result, Vec::<i32>::new());
3787	}
3788
3789	/// Tests `extend` on a singleton vector.
3790	#[test]
3791	fn extend_singleton() {
3792		use crate::classes::extend::extend;
3793		let result = extend::<VecBrand, _, _>(|v: Vec<i32>| v.iter().sum::<i32>(), vec![42]);
3794		assert_eq!(result, vec![42]);
3795	}
3796
3797	// -- Ref trait laws --
3798
3799	/// Tests the identity law for RefFunctor: ref_map(deref, v) == v.
3800	#[quickcheck]
3801	fn ref_functor_identity(v: Vec<i32>) -> bool {
3802		use crate::classes::ref_functor::RefFunctor;
3803		VecBrand::ref_map(|x: &i32| *x, &v) == v
3804	}
3805
3806	/// Tests the composition law for RefFunctor:
3807	/// ref_map(|x| g(&f(x)), v) == ref_map(g, ref_map(f, v)).
3808	#[quickcheck]
3809	fn ref_functor_composition(v: Vec<i32>) -> bool {
3810		use crate::classes::ref_functor::RefFunctor;
3811		let f = |x: &i32| x.wrapping_add(1);
3812		let g = |x: &i32| x.wrapping_mul(2);
3813		VecBrand::ref_map(|x: &i32| g(&f(x)), &v) == VecBrand::ref_map(g, &VecBrand::ref_map(f, &v))
3814	}
3815
3816	/// Tests RefFoldable with Additive monoid: ref_fold_map matches iter().sum().
3817	#[quickcheck]
3818	fn ref_foldable_additive(v: Vec<i32>) -> bool {
3819		use crate::{
3820			brands::RcFnBrand,
3821			classes::ref_foldable::RefFoldable,
3822			types::Additive,
3823		};
3824		let result: Additive<i32> =
3825			VecBrand::ref_fold_map::<RcFnBrand, _, _>(|x: &i32| Additive(*x), &v);
3826		result.0 == v.iter().copied().fold(0i32, |a, b| a.wrapping_add(b))
3827	}
3828
3829	/// Tests the left identity law for RefSemimonad:
3830	/// ref_bind(vec![x], |a| vec![*a]) == vec![x].
3831	#[quickcheck]
3832	fn ref_semimonad_left_identity(x: i32) -> bool {
3833		use crate::classes::ref_semimonad::RefSemimonad;
3834		VecBrand::ref_bind(&vec![x], |a: &i32| vec![*a]) == vec![x]
3835	}
3836
3837	/// Tests the associativity law for RefSemimonad:
3838	/// ref_bind(ref_bind(v, f), g) == ref_bind(v, |a| ref_bind(f(a), g)).
3839	#[quickcheck]
3840	fn ref_semimonad_associativity(v: Vec<i32>) -> bool {
3841		use crate::classes::ref_semimonad::RefSemimonad;
3842		let f = |a: &i32| vec![a.wrapping_add(1), a.wrapping_mul(2)];
3843		let g = |b: &i32| vec![b.wrapping_add(10)];
3844		let lhs = VecBrand::ref_bind(&VecBrand::ref_bind(&v, f), g);
3845		let rhs = VecBrand::ref_bind(&v, |a: &i32| VecBrand::ref_bind(&f(a), g));
3846		lhs == rhs
3847	}
3848
3849	/// Tests ParRefFunctor equivalence: par_ref_map(f, v) == ref_map(f, v).
3850	#[quickcheck]
3851	fn par_ref_functor_equivalence(v: Vec<i32>) -> bool {
3852		use crate::classes::{
3853			par_ref_functor::ParRefFunctor,
3854			ref_functor::RefFunctor,
3855		};
3856		let f = |x: &i32| x.wrapping_mul(3).wrapping_add(7);
3857		VecBrand::par_ref_map(f, &v) == VecBrand::ref_map(f, &v)
3858	}
3859
3860	// RefSemimonad Laws (continued)
3861
3862	/// Tests the right identity law for RefSemimonad:
3863	/// `ref_bind(v, |a| ref_pure(a)) == v`.
3864	#[quickcheck]
3865	fn ref_semimonad_right_identity(v: Vec<i32>) -> bool {
3866		use crate::classes::{
3867			ref_pointed::RefPointed,
3868			ref_semimonad::RefSemimonad,
3869		};
3870		VecBrand::ref_bind(&v, |a: &i32| VecBrand::ref_pure(a)) == v
3871	}
3872
3873	// RefLift Laws
3874
3875	/// Tests the identity law for RefLift:
3876	/// `ref_lift2(|_, b| *b, pure(unit), fa) == fa`.
3877	#[quickcheck]
3878	fn ref_lift_identity(v: Vec<i32>) -> bool {
3879		use crate::classes::ref_lift::RefLift;
3880		VecBrand::ref_lift2(|_: &(), b: &i32| *b, &vec![()], &v) == v
3881	}
3882
3883	// RefTraversable Laws
3884
3885	/// Tests the identity law for RefTraversable:
3886	/// `ref_traverse(|a| Identity(*a), ta) == Identity(ta)`.
3887	#[quickcheck]
3888	fn ref_traversable_identity(v: Vec<i32>) -> bool {
3889		use crate::{
3890			classes::ref_traversable::RefTraversable,
3891			types::Identity,
3892		};
3893		let result: Identity<Vec<i32>> =
3894			VecBrand::ref_traverse::<RcFnBrand, _, _, IdentityBrand>(|a: &i32| Identity(*a), &v);
3895		result == Identity(v)
3896	}
3897
3898	/// Tests RefTraversable naturality: ref_traverse(f, ta) produces
3899	/// the same result as traverse(|a| f(&a), ta).
3900	#[quickcheck]
3901	fn ref_traversable_consistent_with_traverse(v: Vec<i32>) -> bool {
3902		use crate::classes::{
3903			ref_traversable::RefTraversable,
3904			traversable::Traversable,
3905		};
3906		let ref_result: Option<Vec<String>> = VecBrand::ref_traverse::<RcFnBrand, _, _, OptionBrand>(
3907			|a: &i32| Some(a.to_string()),
3908			&v,
3909		);
3910		let val_result: Option<Vec<String>> =
3911			VecBrand::traverse::<i32, String, OptionBrand>(|a: i32| Some(a.to_string()), v);
3912		ref_result == val_result
3913	}
3914
3915	// RefCompactable Laws
3916
3917	/// RefCompactable identity: ref_compact of ref_map(Some, &v) preserves values
3918	#[quickcheck]
3919	fn ref_compactable_identity(v: Vec<i32>) -> bool {
3920		let mapped: Vec<Option<i32>> = v.iter().map(|a| Some(*a)).collect();
3921		explicit::compact::<VecBrand, _, _, _>(&mapped) == v
3922	}
3923
3924	// RefAlt Laws
3925
3926	/// RefAlt associativity
3927	#[quickcheck]
3928	fn ref_alt_associativity(
3929		x: Vec<i32>,
3930		y: Vec<i32>,
3931		z: Vec<i32>,
3932	) -> bool {
3933		explicit::alt::<VecBrand, _, _, _>(&explicit::alt::<VecBrand, _, _, _>(&x, &y), &z)
3934			== explicit::alt::<VecBrand, _, _, _>(&x, &explicit::alt::<VecBrand, _, _, _>(&y, &z))
3935	}
3936
3937	/// RefAlt distributivity with RefFunctor
3938	#[quickcheck]
3939	fn ref_alt_distributivity(
3940		x: Vec<i32>,
3941		y: Vec<i32>,
3942	) -> bool {
3943		let f = |a: &i32| a.wrapping_mul(2);
3944		explicit::map::<VecBrand, _, _, _, _>(f, &explicit::alt::<VecBrand, _, _, _>(&x, &y))
3945			== explicit::alt::<VecBrand, _, _, _>(
3946				&explicit::map::<VecBrand, _, _, _, _>(f, &x),
3947				&explicit::map::<VecBrand, _, _, _, _>(f, &y),
3948			)
3949	}
3950}