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