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	#[cfg(feature = "rayon")]
8	use rayon::prelude::*;
9	use {
10		crate::{
11			Apply,
12			brands::{
13				OptionBrand,
14				VecBrand,
15			},
16			classes::{
17				Alt,
18				Applicative,
19				ApplyFirst,
20				ApplySecond,
21				CloneableFn,
22				Compactable,
23				Filterable,
24				Foldable,
25				Functor,
26				Lift,
27				Monoid,
28				ParFoldable,
29				Plus,
30				Pointed,
31				Semiapplicative,
32				Semigroup,
33				Semimonad,
34				SendCloneableFn,
35				Traversable,
36				Witherable,
37				foldable_with_index::FoldableWithIndex,
38				functor_with_index::FunctorWithIndex,
39				traversable_with_index::TraversableWithIndex,
40			},
41			impl_kind,
42			kinds::*,
43		},
44		fp_macros::*,
45	};
46
47	impl_kind! {
48		for VecBrand {
49			type Of<'a, A: 'a>: 'a = Vec<A>;
50		}
51	}
52
53	impl VecBrand {
54		/// Constructs a new vector by prepending a value to an existing vector.
55		///
56		/// This method creates a new vector with the given head element followed by the elements of the tail vector.
57		#[document_signature]
58		///
59		#[document_type_parameters("The type of the elements in the vector.")]
60		///
61		#[document_parameters(
62			"A value to prepend to the vector.",
63			"A vector to prepend the value to."
64		)]
65		///
66		#[document_returns(
67			"A new vector consisting of the `head` element prepended to the `tail` vector."
68		)]
69		#[document_examples]
70		///
71		/// ```
72		/// use fp_library::brands::VecBrand;
73		///
74		/// let head = 1;
75		/// let tail = vec![2, 3];
76		/// let new_vec = VecBrand::construct(head, tail);
77		/// assert_eq!(new_vec, vec![1, 2, 3]);
78		///
79		/// let empty_tail = vec![];
80		/// let single_element = VecBrand::construct(42, empty_tail);
81		/// assert_eq!(single_element, vec![42]);
82		/// ```
83		pub fn construct<A>(
84			head: A,
85			tail: Vec<A>,
86		) -> Vec<A>
87		where
88			A: Clone, {
89			[vec![head], tail].concat()
90		}
91
92		/// Deconstructs a slice into its head element and tail vector.
93		///
94		/// This method splits a slice into its first element and the rest of the elements as a new vector.
95		#[document_signature]
96		///
97		#[document_type_parameters("The type of the elements in the vector.")]
98		///
99		#[document_parameters("The vector slice to deconstruct.")]
100		///
101		#[document_returns(
102			"An [`Option`] containing a tuple of the head element and the remaining tail vector, or [`None`] if the slice is empty."
103		)]
104		///
105		#[document_examples]
106		///
107		/// ```
108		/// use fp_library::brands::VecBrand;
109		///
110		/// let vec = vec![1, 2, 3];
111		/// let deconstructed = VecBrand::deconstruct(&vec);
112		/// assert_eq!(deconstructed, Some((1, vec![2, 3])));
113		///
114		/// let empty: Vec<i32> = vec![];
115		/// assert_eq!(VecBrand::deconstruct(&empty), None);
116		/// ```
117		pub fn deconstruct<A>(slice: &[A]) -> Option<(A, Vec<A>)>
118		where
119			A: Clone, {
120			match slice {
121				[] => None,
122				[head, tail @ ..] => Some((head.clone(), tail.to_vec())),
123			}
124		}
125	}
126
127	impl Functor for VecBrand {
128		/// Maps a function over the vector.
129		///
130		/// This method applies a function to each element of the vector, producing a new vector with the transformed values.
131		#[document_signature]
132		///
133		#[document_type_parameters(
134			"The lifetime of the elements.",
135			"The type of the elements in the vector.",
136			"The type of the elements in the resulting vector."
137		)]
138		///
139		#[document_parameters("The function to apply to each element.", "The vector to map over.")]
140		///
141		#[document_returns("A new vector containing the results of applying the function.")]
142		///
143		#[document_examples]
144		///
145		/// ```
146		/// use fp_library::{
147		/// 	brands::*,
148		/// 	functions::*,
149		/// };
150		///
151		/// assert_eq!(map::<VecBrand, _, _>(|x: i32| x * 2, vec![1, 2, 3]), vec![2, 4, 6]);
152		/// ```
153		fn map<'a, A: 'a, B: 'a>(
154			func: impl Fn(A) -> B + 'a,
155			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
156		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
157			fa.into_iter().map(func).collect()
158		}
159	}
160
161	impl Lift for VecBrand {
162		/// Lifts a binary function into the vector context (Cartesian product).
163		///
164		/// This method applies a binary function to all pairs of elements from two vectors, producing a new vector containing the results (Cartesian product).
165		#[document_signature]
166		///
167		#[document_type_parameters(
168			"The lifetime of the elements.",
169			"The type of the elements in the first vector.",
170			"The type of the elements in the second vector.",
171			"The type of the elements in the resulting vector."
172		)]
173		///
174		#[document_parameters(
175			"The binary function to apply.",
176			"The first vector.",
177			"The second vector."
178		)]
179		///
180		#[document_returns(
181			"A new vector containing the results of applying the function to all pairs of elements."
182		)]
183		#[document_examples]
184		///
185		/// ```
186		/// use fp_library::{
187		/// 	brands::*,
188		/// 	functions::*,
189		/// };
190		///
191		/// assert_eq!(
192		/// 	lift2::<VecBrand, _, _, _>(|x, y| x + y, vec![1, 2], vec![10, 20]),
193		/// 	vec![11, 21, 12, 22]
194		/// );
195		/// ```
196		fn lift2<'a, A, B, C>(
197			func: impl Fn(A, B) -> C + 'a,
198			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
199			fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
200		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
201		where
202			A: Clone + 'a,
203			B: Clone + 'a,
204			C: 'a, {
205			fa.iter().flat_map(|a| fb.iter().map(|b| func(a.clone(), b.clone()))).collect()
206		}
207	}
208
209	impl Pointed for VecBrand {
210		/// Wraps a value in a vector.
211		///
212		/// This method creates a new vector containing the single given value.
213		#[document_signature]
214		///
215		#[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
216		///
217		#[document_parameters("The value to wrap.")]
218		///
219		#[document_returns("A vector containing the single value.")]
220		///
221		#[document_examples]
222		///
223		/// ```
224		/// use fp_library::{
225		/// 	brands::VecBrand,
226		/// 	functions::*,
227		/// };
228		///
229		/// assert_eq!(pure::<VecBrand, _>(5), vec![5]);
230		/// ```
231		fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
232			vec![a]
233		}
234	}
235
236	impl ApplyFirst for VecBrand {}
237	impl ApplySecond for VecBrand {}
238
239	impl Semiapplicative for VecBrand {
240		/// Applies wrapped functions to wrapped values (Cartesian product).
241		///
242		/// This method applies each function in the first vector to each value in the second vector, producing a new vector containing all the results.
243		#[document_signature]
244		///
245		#[document_type_parameters(
246			"The lifetime of the values.",
247			"The brand of the cloneable function wrapper.",
248			"The type of the input values.",
249			"The type of the output values."
250		)]
251		///
252		#[document_parameters(
253			"The vector containing the functions.",
254			"The vector containing the values."
255		)]
256		///
257		#[document_returns(
258			"A new vector containing the results of applying each function to each value."
259		)]
260		#[document_examples]
261		///
262		/// ```
263		/// use fp_library::{
264		/// 	brands::*,
265		/// 	classes::*,
266		/// 	functions::*,
267		/// };
268		///
269		/// let funcs = vec![
270		/// 	cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| x + 1),
271		/// 	cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2),
272		/// ];
273		/// assert_eq!(apply::<RcFnBrand, VecBrand, _, _>(funcs, vec![1, 2]), vec![2, 3, 2, 4]);
274		/// ```
275		fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
276			ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
277			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
278		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
279			ff.iter().flat_map(|f| fa.iter().map(move |a| f(a.clone()))).collect()
280		}
281	}
282
283	impl Semimonad for VecBrand {
284		/// Chains vector computations (`flat_map`).
285		///
286		/// This method applies a function that returns a vector to each element of the input vector, and then flattens the result.
287		#[document_signature]
288		///
289		#[document_type_parameters(
290			"The lifetime of the elements.",
291			"The type of the elements in the input vector.",
292			"The type of the elements in the output vector."
293		)]
294		///
295		#[document_parameters(
296			"The first vector.",
297			"The function to apply to each element, returning a vector."
298		)]
299		///
300		#[document_returns("A new vector containing the flattened results.")]
301		#[document_examples]
302		///
303		/// ```
304		/// use fp_library::{
305		/// 	brands::VecBrand,
306		/// 	functions::*,
307		/// };
308		///
309		/// assert_eq!(bind::<VecBrand, _, _>(vec![1, 2], |x| vec![x, x * 2]), vec![1, 2, 2, 4]);
310		/// ```
311		fn bind<'a, A: 'a, B: 'a>(
312			ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
313			func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
314		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
315			ma.into_iter().flat_map(func).collect()
316		}
317	}
318
319	impl Alt for VecBrand {
320		/// Concatenates two vectors.
321		///
322		/// This is the same as [`Semigroup::append`] for `Vec`, providing an
323		/// associative choice operation for the `Vec` type constructor.
324		#[document_signature]
325		///
326		#[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
327		///
328		#[document_parameters("The first vector.", "The second vector.")]
329		///
330		#[document_returns("The concatenated vector.")]
331		#[document_examples]
332		///
333		/// ```
334		/// use fp_library::{
335		/// 	brands::*,
336		/// 	classes::*,
337		/// 	functions::*,
338		/// };
339		///
340		/// let x = vec![1, 2];
341		/// let y = vec![3, 4];
342		/// assert_eq!(alt::<VecBrand, _>(x, y), vec![1, 2, 3, 4]);
343		/// ```
344		fn alt<'a, A: 'a>(
345			fa1: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
346			fa2: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
347		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
348			let mut result = fa1;
349			result.extend(fa2);
350			result
351		}
352	}
353
354	impl Plus for VecBrand {
355		/// Returns an empty vector, the identity element for [`alt`](Alt::alt).
356		#[document_signature]
357		///
358		#[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
359		///
360		#[document_returns("An empty vector.")]
361		#[document_examples]
362		///
363		/// ```
364		/// use fp_library::{
365		/// 	brands::*,
366		/// 	functions::*,
367		/// };
368		///
369		/// let x: Vec<i32> = plus_empty::<VecBrand, i32>();
370		/// assert_eq!(x, vec![]);
371		/// ```
372		fn empty<'a, A: 'a>() -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
373			Vec::new()
374		}
375	}
376
377	impl Foldable for VecBrand {
378		/// Folds the vector from the right.
379		///
380		/// This method performs a right-associative fold of the vector.
381		#[document_signature]
382		///
383		#[document_type_parameters(
384			"The lifetime of the elements.",
385			"The brand of the cloneable function to use.",
386			"The type of the elements in the vector.",
387			"The type of the accumulator."
388		)]
389		///
390		#[document_parameters("The folding function.", "The initial value.", "The vector to fold.")]
391		///
392		#[document_returns("The final accumulator value.")]
393		///
394		#[document_examples]
395		///
396		/// ```
397		/// use fp_library::{
398		/// 	brands::*,
399		/// 	functions::*,
400		/// };
401		///
402		/// assert_eq!(fold_right::<RcFnBrand, VecBrand, _, _>(|x: i32, acc| x + acc, 0, vec![1, 2, 3]), 6);
403		/// ```
404		fn fold_right<'a, FnBrand, A: 'a + Clone, B: 'a>(
405			func: impl Fn(A, B) -> B + 'a,
406			initial: B,
407			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
408		) -> B
409		where
410			FnBrand: CloneableFn + 'a, {
411			fa.into_iter().rev().fold(initial, |acc, x| func(x, acc))
412		}
413
414		/// Folds the vector from the left.
415		///
416		/// This method performs a left-associative fold of the vector.
417		#[document_signature]
418		///
419		#[document_type_parameters(
420			"The lifetime of the elements.",
421			"The brand of the cloneable function to use.",
422			"The type of the elements in the vector.",
423			"The type of the accumulator."
424		)]
425		///
426		#[document_parameters(
427			"The function to apply to the accumulator and each element.",
428			"The initial value of the accumulator.",
429			"The vector to fold."
430		)]
431		///
432		#[document_returns("The final accumulator value.")]
433		#[document_examples]
434		///
435		/// ```
436		/// use fp_library::{
437		/// 	brands::*,
438		/// 	functions::*,
439		/// };
440		///
441		/// assert_eq!(fold_left::<RcFnBrand, VecBrand, _, _>(|acc, x: i32| acc + x, 0, vec![1, 2, 3]), 6);
442		/// ```
443		fn fold_left<'a, FnBrand, A: 'a + Clone, B: 'a>(
444			func: impl Fn(B, A) -> B + 'a,
445			initial: B,
446			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
447		) -> B
448		where
449			FnBrand: CloneableFn + 'a, {
450			fa.into_iter().fold(initial, func)
451		}
452
453		/// Maps the values to a monoid and combines them.
454		///
455		/// This method maps each element of the vector to a monoid and then combines the results using the monoid's `append` operation.
456		#[document_signature]
457		///
458		#[document_type_parameters(
459			"The lifetime of the elements.",
460			"The brand of the cloneable function to use.",
461			"The type of the elements in the vector.",
462			"The type of the monoid."
463		)]
464		///
465		#[document_parameters("The mapping function.", "The vector to fold.")]
466		///
467		#[document_returns("The combined monoid value.")]
468		///
469		#[document_examples]
470		///
471		/// ```
472		/// use fp_library::{
473		/// 	brands::*,
474		/// 	functions::*,
475		/// };
476		///
477		/// assert_eq!(
478		/// 	fold_map::<RcFnBrand, VecBrand, _, _>(|x: i32| x.to_string(), vec![1, 2, 3]),
479		/// 	"123".to_string()
480		/// );
481		/// ```
482		fn fold_map<'a, FnBrand, A: 'a + Clone, M>(
483			func: impl Fn(A) -> M + 'a,
484			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
485		) -> M
486		where
487			M: Monoid + 'a,
488			FnBrand: CloneableFn + 'a, {
489			fa.into_iter().map(func).fold(M::empty(), |acc, x| M::append(acc, x))
490		}
491	}
492
493	impl Traversable for VecBrand {
494		/// Traverses the vector with an applicative function.
495		///
496		/// This method maps each element of the vector to a computation, evaluates them, and combines the results into an applicative context.
497		#[document_signature]
498		///
499		#[document_type_parameters(
500			"The lifetime of the elements.",
501			"The type of the elements in the traversable structure.",
502			"The type of the elements in the resulting traversable structure.",
503			"The applicative context."
504		)]
505		///
506		#[document_parameters(
507			"The function to apply to each element, returning a value in an applicative context.",
508			"The vector to traverse."
509		)]
510		///
511		#[document_returns("The vector wrapped in the applicative context.")]
512		#[document_examples]
513		///
514		/// ```
515		/// use fp_library::{
516		/// 	brands::{
517		/// 		OptionBrand,
518		/// 		VecBrand,
519		/// 	},
520		/// 	functions::*,
521		/// };
522		///
523		/// assert_eq!(
524		/// 	traverse::<VecBrand, _, _, OptionBrand>(|x| Some(x * 2), vec![1, 2, 3]),
525		/// 	Some(vec![2, 4, 6])
526		/// );
527		/// ```
528		fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
529			func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
530			ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
531		) -> 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>)>)
532		where
533			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
534			Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
535			let len = ta.len();
536			ta.into_iter().fold(F::pure(Vec::with_capacity(len)), |acc, x| {
537				F::lift2(
538					|mut v, b| {
539						v.push(b);
540						v
541					},
542					acc,
543					func(x),
544				)
545			})
546		}
547
548		/// Sequences a vector of applicative.
549		///
550		/// This method evaluates the computations inside the vector and accumulates the results into an applicative context.
551		#[document_signature]
552		///
553		#[document_type_parameters(
554			"The lifetime of the elements.",
555			"The type of the elements in the traversable structure.",
556			"The applicative context."
557		)]
558		///
559		#[document_parameters("The vector containing the applicative values.")]
560		///
561		#[document_returns("The vector wrapped in the applicative context.")]
562		///
563		#[document_examples]
564		///
565		/// ```
566		/// use fp_library::{
567		/// 	brands::{
568		/// 		OptionBrand,
569		/// 		VecBrand,
570		/// 	},
571		/// 	functions::*,
572		/// };
573		///
574		/// assert_eq!(sequence::<VecBrand, _, OptionBrand>(vec![Some(1), Some(2)]), Some(vec![1, 2]));
575		/// ```
576		fn sequence<'a, A: 'a + Clone, F: Applicative>(
577			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>)>)
578		) -> 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>)>)
579		where
580			Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
581			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
582			let len = ta.len();
583			ta.into_iter().fold(F::pure(Vec::with_capacity(len)), |acc, x| {
584				F::lift2(
585					|mut v, a| {
586						v.push(a);
587						v
588					},
589					acc,
590					x,
591				)
592			})
593		}
594	}
595
596	impl FunctorWithIndex<usize> for VecBrand {
597		/// Maps a function over the vector, providing the index of each element.
598		#[document_signature]
599		#[document_type_parameters(
600			"The lifetime of the elements.",
601			"The type of the elements in the vector.",
602			"The type of the elements in the resulting vector."
603		)]
604		#[document_parameters(
605			"The function to apply to each element and its index.",
606			"The vector to map over."
607		)]
608		#[document_returns("A new vector containing the results of applying the function.")]
609		#[document_examples]
610		///
611		/// ```
612		/// use fp_library::{
613		/// 	brands::VecBrand,
614		/// 	functions::*,
615		/// };
616		/// let v = vec![10, 20, 30];
617		/// // Use `map_with_index` via the method on the trait, or a helper function if one existed.
618		/// // Since there's no helper function in `functions.rs` yet, we use explicit syntax or call it via trait.
619		/// use fp_library::classes::functor_with_index::FunctorWithIndex;
620		/// let mapped = <VecBrand as FunctorWithIndex<usize>>::map_with_index(|i, x| x + i as i32, v);
621		/// assert_eq!(mapped, vec![10, 21, 32]);
622		/// ```
623		fn map_with_index<'a, A: 'a, B: 'a>(
624			f: impl Fn(usize, A) -> B + 'a,
625			fa: Vec<A>,
626		) -> Vec<B> {
627			fa.into_iter().enumerate().map(|(i, a)| f(i, a)).collect()
628		}
629	}
630
631	impl FoldableWithIndex<usize> for VecBrand {
632		/// Folds the vector using a monoid, providing the index of each element.
633		#[document_signature]
634		#[document_type_parameters(
635			"The lifetime of the elements.",
636			"The type of the elements in the vector.",
637			"The monoid type."
638		)]
639		#[document_parameters(
640			"The function to apply to each element and its index.",
641			"The vector to fold."
642		)]
643		#[document_returns("The combined monoid value.")]
644		#[document_examples]
645		///
646		/// ```
647		/// use fp_library::{
648		/// 	brands::VecBrand,
649		/// 	classes::foldable_with_index::FoldableWithIndex,
650		/// 	functions::*,
651		/// };
652		/// let v = vec![10, 20, 30];
653		/// let s = <VecBrand as FoldableWithIndex<usize>>::fold_map_with_index(
654		/// 	|i, x| format!("{}:{}", i, x),
655		/// 	v,
656		/// );
657		/// assert_eq!(s, "0:101:202:30");
658		/// ```
659		fn fold_map_with_index<'a, A: 'a, R: Monoid>(
660			f: impl Fn(usize, A) -> R + 'a,
661			fa: Vec<A>,
662		) -> R {
663			fa.into_iter()
664				.enumerate()
665				.map(|(i, a)| f(i, a))
666				.fold(R::empty(), |acc, x| R::append(acc, x))
667		}
668	}
669
670	impl TraversableWithIndex<usize> for VecBrand {
671		/// Traverses the vector with an applicative function, providing the index of each element.
672		#[document_signature]
673		#[document_type_parameters(
674			"The lifetime of the elements.",
675			"The type of the elements in the vector.",
676			"The type of the elements in the resulting vector.",
677			"The applicative context."
678		)]
679		#[document_parameters(
680			"The function to apply to each element and its index, returning a value in an applicative context.",
681			"The vector to traverse."
682		)]
683		#[document_returns("The vector wrapped in the applicative context.")]
684		#[document_examples]
685		///
686		/// ```
687		/// use fp_library::{
688		/// 	brands::{
689		/// 		OptionBrand,
690		/// 		VecBrand,
691		/// 	},
692		/// 	classes::traversable_with_index::TraversableWithIndex,
693		/// 	functions::*,
694		/// };
695		/// let v = vec![10, 20, 30];
696		/// let t = <VecBrand as TraversableWithIndex<usize>>::traverse_with_index::<i32, i32, OptionBrand>(
697		/// 	|i, x| Some(x + i as i32),
698		/// 	v,
699		/// );
700		/// assert_eq!(t, Some(vec![10, 21, 32]));
701		/// ```
702		fn traverse_with_index<'a, A: 'a, B: 'a + Clone, M: Applicative>(
703			f: impl Fn(usize, A) -> M::Of<'a, B> + 'a,
704			ta: Vec<A>,
705		) -> M::Of<'a, Vec<B>> {
706			let len = ta.len();
707			ta.into_iter().enumerate().fold(M::pure(Vec::with_capacity(len)), |acc, (i, x)| {
708				M::lift2(
709					|mut v, b| {
710						v.push(b);
711						v
712					},
713					acc,
714					f(i, x),
715				)
716			})
717		}
718	}
719
720	#[document_type_parameters("The type of the elements in the vector.")]
721	impl<A: Clone> Semigroup for Vec<A> {
722		/// Appends one vector to another.
723		///
724		/// This method concatenates two vectors.
725		#[document_signature]
726		///
727		#[document_parameters("The first vector.", "The second vector.")]
728		///
729		#[document_returns("The concatenated vector.")]
730		///
731		#[document_examples]
732		///
733		/// ```
734		/// use fp_library::functions::*;
735		///
736		/// assert_eq!(append(vec![1, 2], vec![3, 4]), vec![1, 2, 3, 4]);
737		/// ```
738		fn append(
739			a: Self,
740			b: Self,
741		) -> Self {
742			[a, b].concat()
743		}
744	}
745
746	#[document_type_parameters("The type of the elements in the vector.")]
747	impl<A: Clone> Monoid for Vec<A> {
748		/// Returns an empty vector.
749		///
750		/// This method returns a new, empty vector.
751		#[document_signature]
752		///
753		#[document_returns("An empty vector.")]
754		///
755		#[document_examples]
756		///
757		/// ```
758		/// use fp_library::functions::*;
759		///
760		/// assert_eq!(empty::<Vec<i32>>(), vec![]);
761		/// ```
762		fn empty() -> Self {
763			Vec::new()
764		}
765	}
766
767	impl ParFoldable for VecBrand {
768		/// Maps values to a monoid and combines them in parallel.
769		///
770		/// This method maps each element of the vector to a monoid and then combines the results using the monoid's `append` operation. The mapping and combination operations may be executed in parallel.
771		///
772		/// **Note: The `rayon` feature must be enabled to use parallel iteration.**
773		#[document_signature]
774		///
775		#[document_type_parameters(
776			"The lifetime of the elements.",
777			"The brand of the cloneable function wrapper.",
778			"The element type.",
779			"The monoid type."
780		)]
781		///
782		#[document_parameters(
783			"The thread-safe function to map each element to a monoid.",
784			"The vector to fold."
785		)]
786		///
787		#[document_returns("The combined monoid value.")]
788		#[document_examples]
789		///
790		/// ```
791		/// use fp_library::{
792		/// 	brands::*,
793		/// 	functions::*,
794		/// };
795		///
796		/// let v = vec![1, 2, 3];
797		/// let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
798		/// assert_eq!(par_fold_map::<ArcFnBrand, VecBrand, _, _>(f, v), "123".to_string());
799		/// ```
800		fn par_fold_map<'a, FnBrand, A, M>(
801			func: <FnBrand as SendCloneableFn>::SendOf<'a, A, M>,
802			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
803		) -> M
804		where
805			FnBrand: 'a + SendCloneableFn,
806			A: 'a + Clone + Send + Sync,
807			M: Monoid + Send + Sync + 'a, {
808			#[cfg(feature = "rayon")]
809			{
810				#[allow(clippy::redundant_closure)] // Required: Arc<dyn Fn> doesn't impl Fn
811				fa.into_par_iter().map(|a| func(a)).reduce(M::empty, |acc, m| M::append(acc, m))
812			}
813			#[cfg(not(feature = "rayon"))]
814			{
815				#[allow(clippy::redundant_closure)] // Required for move semantics
816				fa.into_iter().map(|a| func(a)).fold(M::empty(), |acc, m| M::append(acc, m))
817			}
818		}
819	}
820
821	impl Compactable for VecBrand {
822		/// Compacts a vector of options.
823		///
824		/// This method flattens a vector of options, discarding `None` values.
825		#[document_signature]
826		///
827		#[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
828		///
829		#[document_parameters("The vector of options.")]
830		///
831		#[document_returns("The flattened vector.")]
832		///
833		#[document_examples]
834		///
835		/// ```
836		/// use fp_library::{
837		/// 	brands::VecBrand,
838		/// 	functions::*,
839		/// };
840		///
841		/// let x = vec![Some(1), None, Some(2)];
842		/// let y = compact::<VecBrand, _>(x);
843		/// assert_eq!(y, vec![1, 2]);
844		/// ```
845		fn compact<'a, A: 'a>(
846			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
847			'a,
848			Apply!(<OptionBrand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
849		>)
850		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
851			fa.into_iter().flatten().collect()
852		}
853
854		/// Separates a vector of results.
855		///
856		/// This method separates a vector of results into a pair of vectors.
857		#[document_signature]
858		///
859		#[document_type_parameters(
860			"The lifetime of the elements.",
861			"The type of the error value.",
862			"The type of the success value."
863		)]
864		///
865		#[document_parameters("The vector of results.")]
866		///
867		#[document_returns("A pair of vectors.")]
868		///
869		#[document_examples]
870		///
871		/// ```
872		/// use fp_library::{
873		/// 	brands::*,
874		/// 	functions::*,
875		/// };
876		///
877		/// let x = vec![Ok(1), Err("error"), Ok(2)];
878		/// let (errs, oks) = separate::<VecBrand, _, _>(x);
879		/// assert_eq!(oks, vec![1, 2]);
880		/// assert_eq!(errs, vec!["error"]);
881		/// ```
882		fn separate<'a, E: 'a, O: 'a>(
883			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>)
884		) -> (
885			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
886			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
887		) {
888			let mut oks = Vec::new();
889			let mut errs = Vec::new();
890			for result in fa {
891				match result {
892					Ok(o) => oks.push(o),
893					Err(e) => errs.push(e),
894				}
895			}
896			(errs, oks)
897		}
898	}
899
900	impl Filterable for VecBrand {
901		/// Partitions a vector based on a function that returns a result.
902		///
903		/// This method partitions a vector based on a function that returns a result.
904		#[document_signature]
905		///
906		#[document_type_parameters(
907			"The lifetime of the elements.",
908			"The type of the input value.",
909			"The type of the error value.",
910			"The type of the success value."
911		)]
912		///
913		#[document_parameters("The function to apply.", "The vector to partition.")]
914		///
915		#[document_returns("A pair of vectors.")]
916		///
917		#[document_examples]
918		///
919		/// ```
920		/// use fp_library::{
921		/// 	brands::*,
922		/// 	functions::*,
923		/// };
924		///
925		/// let x = vec![1, 2, 3, 4];
926		/// let (errs, oks) =
927		/// 	partition_map::<VecBrand, _, _, _>(|a| if a % 2 == 0 { Ok(a) } else { Err(a) }, x);
928		/// assert_eq!(oks, vec![2, 4]);
929		/// assert_eq!(errs, vec![1, 3]);
930		/// ```
931		fn partition_map<'a, A: 'a, E: 'a, O: 'a>(
932			func: impl Fn(A) -> Result<O, E> + 'a,
933			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
934		) -> (
935			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
936			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
937		) {
938			let mut oks = Vec::new();
939			let mut errs = Vec::new();
940			for a in fa {
941				match func(a) {
942					Ok(o) => oks.push(o),
943					Err(e) => errs.push(e),
944				}
945			}
946			(errs, oks)
947		}
948
949		/// Partitions a vector based on a predicate.
950		///
951		/// This method partitions a vector based on a predicate.
952		#[document_signature]
953		///
954		#[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
955		///
956		#[document_parameters("The predicate.", "The vector to partition.")]
957		///
958		#[document_returns("A pair of vectors.")]
959		///
960		#[document_examples]
961		///
962		/// ```
963		/// use fp_library::{
964		/// 	brands::*,
965		/// 	functions::*,
966		/// };
967		///
968		/// let x = vec![1, 2, 3, 4];
969		/// let (not_satisfied, satisfied) = partition::<VecBrand, _>(|a| a % 2 == 0, x);
970		/// assert_eq!(satisfied, vec![2, 4]);
971		/// assert_eq!(not_satisfied, vec![1, 3]);
972		/// ```
973		fn partition<'a, A: 'a + Clone>(
974			func: impl Fn(A) -> bool + 'a,
975			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
976		) -> (
977			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
978			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
979		) {
980			let (satisfied, not_satisfied): (Vec<A>, Vec<A>) =
981				fa.into_iter().partition(|a| func(a.clone()));
982			(not_satisfied, satisfied)
983		}
984
985		/// Maps a function over a vector and filters out `None` results.
986		///
987		/// This method maps a function over a vector and filters out `None` results.
988		#[document_signature]
989		///
990		#[document_type_parameters(
991			"The lifetime of the elements.",
992			"The type of the input value.",
993			"The type of the result of applying the function."
994		)]
995		///
996		#[document_parameters("The function to apply.", "The vector to filter and map.")]
997		///
998		#[document_returns("The filtered and mapped vector.")]
999		///
1000		#[document_examples]
1001		///
1002		/// ```
1003		/// use fp_library::{
1004		/// 	brands::VecBrand,
1005		/// 	functions::*,
1006		/// };
1007		///
1008		/// let x = vec![1, 2, 3, 4];
1009		/// let y = filter_map::<VecBrand, _, _>(|a| if a % 2 == 0 { Some(a * 2) } else { None }, x);
1010		/// assert_eq!(y, vec![4, 8]);
1011		/// ```
1012		fn filter_map<'a, A: 'a, B: 'a>(
1013			func: impl Fn(A) -> Option<B> + 'a,
1014			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1015		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1016			fa.into_iter().filter_map(func).collect()
1017		}
1018
1019		/// Filters a vector based on a predicate.
1020		///
1021		/// This method filters a vector based on a predicate.
1022		#[document_signature]
1023		///
1024		#[document_type_parameters("The lifetime of the elements.", "The type of the elements.")]
1025		///
1026		#[document_parameters("The predicate.", "The vector to filter.")]
1027		///
1028		#[document_returns("The filtered vector.")]
1029		///
1030		#[document_examples]
1031		///
1032		/// ```
1033		/// use fp_library::{
1034		/// 	brands::VecBrand,
1035		/// 	functions::*,
1036		/// };
1037		///
1038		/// let x = vec![1, 2, 3, 4];
1039		/// let y = filter::<VecBrand, _>(|a| a % 2 == 0, x);
1040		/// assert_eq!(y, vec![2, 4]);
1041		/// ```
1042		fn filter<'a, A: 'a + Clone>(
1043			func: impl Fn(A) -> bool + 'a,
1044			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1045		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
1046			fa.into_iter().filter(|a| func(a.clone())).collect()
1047		}
1048	}
1049
1050	impl Witherable for VecBrand {
1051		/// Partitions a vector based on a function that returns a result in an applicative context.
1052		///
1053		/// This method partitions a vector based on a function that returns a result in an applicative context.
1054		#[document_signature]
1055		///
1056		#[document_type_parameters(
1057			"The lifetime of the elements.",
1058			"The applicative context.",
1059			"The type of the input value.",
1060			"The type of the error value.",
1061			"The type of the success value."
1062		)]
1063		///
1064		#[document_parameters("The function to apply.", "The vector to partition.")]
1065		///
1066		#[document_returns("The partitioned vector wrapped in the applicative context.")]
1067		///
1068		#[document_examples]
1069		///
1070		/// ```
1071		/// use fp_library::{
1072		/// 	brands::*,
1073		/// 	functions::*,
1074		/// };
1075		///
1076		/// let x = vec![1, 2, 3, 4];
1077		/// let y = wilt::<VecBrand, OptionBrand, _, _, _>(
1078		/// 	|a| Some(if a % 2 == 0 { Ok(a) } else { Err(a) }),
1079		/// 	x,
1080		/// );
1081		/// assert_eq!(y, Some((vec![1, 3], vec![2, 4])));
1082		/// ```
1083		fn wilt<'a, M: Applicative, A: 'a + Clone, E: 'a + Clone, O: 'a + Clone>(
1084			func: impl Fn(A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>)
1085			+ 'a,
1086			ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1087		) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
1088		'a,
1089		(
1090			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, E>),
1091			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, O>),
1092		),
1093	>)
1094		where
1095			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>): Clone,
1096			Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Result<O, E>>): Clone, {
1097			ta.into_iter().fold(M::pure((Vec::new(), Vec::new())), |acc, x| {
1098				M::lift2(
1099					|mut pair, res| {
1100						match res {
1101							Ok(o) => pair.1.push(o),
1102							Err(e) => pair.0.push(e),
1103						}
1104						pair
1105					},
1106					acc,
1107					func(x),
1108				)
1109			})
1110		}
1111
1112		/// Maps a function over a vector and filters out `None` results in an applicative context.
1113		///
1114		/// This method maps a function over a vector and filters out `None` results in an applicative context.
1115		#[document_signature]
1116		///
1117		#[document_type_parameters(
1118			"The lifetime of the values.",
1119			"The applicative context.",
1120			"The type of the elements in the input structure.",
1121			"The type of the result of applying the function."
1122		)]
1123		///
1124		#[document_parameters(
1125			"The function to apply to each element, returning an `Option` in an applicative context.",
1126			"The vector to filter and map."
1127		)]
1128		///
1129		#[document_returns("The filtered and mapped vector wrapped in the applicative context.")]
1130		#[document_examples]
1131		///
1132		/// ```
1133		/// use fp_library::{
1134		/// 	brands::{
1135		/// 		OptionBrand,
1136		/// 		VecBrand,
1137		/// 	},
1138		/// 	functions::*,
1139		/// };
1140		///
1141		/// let x = vec![1, 2, 3, 4];
1142		/// let y = wither::<VecBrand, OptionBrand, _, _>(
1143		/// 	|a| Some(if a % 2 == 0 { Some(a * 2) } else { None }),
1144		/// 	x,
1145		/// );
1146		/// assert_eq!(y, Some(vec![4, 8]));
1147		/// ```
1148		fn wither<'a, M: Applicative, A: 'a + Clone, B: 'a + Clone>(
1149			func: impl Fn(A) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>) + 'a,
1150			ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1151		) -> Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<
1152		'a,
1153		Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
1154	>)
1155		where
1156			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>): Clone,
1157			Apply!(<M as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Option<B>>): Clone, {
1158			ta.into_iter().fold(M::pure(Vec::new()), |acc, x| {
1159				M::lift2(
1160					|mut v, opt_b| {
1161						if let Some(b) = opt_b {
1162							v.push(b);
1163						}
1164						v
1165					},
1166					acc,
1167					func(x),
1168				)
1169			})
1170		}
1171	}
1172}
1173
1174#[cfg(test)]
1175mod tests {
1176
1177	use {
1178		crate::{
1179			brands::*,
1180			classes::CloneableFn,
1181			functions::*,
1182		},
1183		quickcheck_macros::quickcheck,
1184	};
1185
1186	// Functor Laws
1187
1188	/// Tests the identity law for Functor.
1189	#[quickcheck]
1190	fn functor_identity(x: Vec<i32>) -> bool {
1191		map::<VecBrand, _, _>(identity, x.clone()) == x
1192	}
1193
1194	/// Tests the composition law for Functor.
1195	#[quickcheck]
1196	fn functor_composition(x: Vec<i32>) -> bool {
1197		let f = |x: i32| x.wrapping_add(1);
1198		let g = |x: i32| x.wrapping_mul(2);
1199		map::<VecBrand, _, _>(compose(f, g), x.clone())
1200			== map::<VecBrand, _, _>(f, map::<VecBrand, _, _>(g, x))
1201	}
1202
1203	// Applicative Laws
1204
1205	/// Tests the identity law for Applicative.
1206	#[quickcheck]
1207	fn applicative_identity(v: Vec<i32>) -> bool {
1208		apply::<RcFnBrand, VecBrand, _, _>(
1209			pure::<VecBrand, _>(<RcFnBrand as CloneableFn>::new(identity)),
1210			v.clone(),
1211		) == v
1212	}
1213
1214	/// Tests the homomorphism law for Applicative.
1215	#[quickcheck]
1216	fn applicative_homomorphism(x: i32) -> bool {
1217		let f = |x: i32| x.wrapping_mul(2);
1218		apply::<RcFnBrand, VecBrand, _, _>(
1219			pure::<VecBrand, _>(<RcFnBrand as CloneableFn>::new(f)),
1220			pure::<VecBrand, _>(x),
1221		) == pure::<VecBrand, _>(f(x))
1222	}
1223
1224	/// Tests the composition law for Applicative.
1225	#[quickcheck]
1226	fn applicative_composition(
1227		w: Vec<i32>,
1228		u_seeds: Vec<i32>,
1229		v_seeds: Vec<i32>,
1230	) -> bool {
1231		let u_fns: Vec<_> = u_seeds
1232			.iter()
1233			.map(|&i| <RcFnBrand as CloneableFn>::new(move |x: i32| x.wrapping_add(i)))
1234			.collect();
1235		let v_fns: Vec<_> = v_seeds
1236			.iter()
1237			.map(|&i| <RcFnBrand as CloneableFn>::new(move |x: i32| x.wrapping_mul(i)))
1238			.collect();
1239
1240		// RHS: u <*> (v <*> w)
1241		let vw = apply::<RcFnBrand, VecBrand, _, _>(v_fns.clone(), w.clone());
1242		let rhs = apply::<RcFnBrand, VecBrand, _, _>(u_fns.clone(), vw);
1243
1244		// LHS: pure(compose) <*> u <*> v <*> w
1245		// equivalent to (u . v) <*> w
1246		// We construct (u . v) manually as the cartesian product of compositions
1247		let uv_fns: Vec<_> = u_fns
1248			.iter()
1249			.flat_map(|uf| {
1250				v_fns.iter().map(move |vf| {
1251					let uf = uf.clone();
1252					let vf = vf.clone();
1253					<RcFnBrand as CloneableFn>::new(move |x| uf(vf(x)))
1254				})
1255			})
1256			.collect();
1257
1258		let lhs = apply::<RcFnBrand, VecBrand, _, _>(uv_fns, w);
1259
1260		lhs == rhs
1261	}
1262
1263	/// Tests the interchange law for Applicative.
1264	#[quickcheck]
1265	fn applicative_interchange(y: i32) -> bool {
1266		// u <*> pure y = pure ($ y) <*> u
1267		let f = |x: i32| x.wrapping_mul(2);
1268		let u = vec![<RcFnBrand as CloneableFn>::new(f)];
1269
1270		let lhs = apply::<RcFnBrand, VecBrand, _, _>(u.clone(), pure::<VecBrand, _>(y));
1271
1272		let rhs_fn =
1273			<RcFnBrand as CloneableFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
1274		let rhs = apply::<RcFnBrand, VecBrand, _, _>(pure::<VecBrand, _>(rhs_fn), u);
1275
1276		lhs == rhs
1277	}
1278
1279	// Semigroup Laws
1280
1281	/// Tests the associativity law for Semigroup.
1282	#[quickcheck]
1283	fn semigroup_associativity(
1284		a: Vec<i32>,
1285		b: Vec<i32>,
1286		c: Vec<i32>,
1287	) -> bool {
1288		append(a.clone(), append(b.clone(), c.clone())) == append(append(a, b), c)
1289	}
1290
1291	// Monoid Laws
1292
1293	/// Tests the left identity law for Monoid.
1294	#[quickcheck]
1295	fn monoid_left_identity(a: Vec<i32>) -> bool {
1296		append(empty::<Vec<i32>>(), a.clone()) == a
1297	}
1298
1299	/// Tests the right identity law for Monoid.
1300	#[quickcheck]
1301	fn monoid_right_identity(a: Vec<i32>) -> bool {
1302		append(a.clone(), empty::<Vec<i32>>()) == a
1303	}
1304
1305	// Monad Laws
1306
1307	/// Tests the left identity law for Monad.
1308	#[quickcheck]
1309	fn monad_left_identity(a: i32) -> bool {
1310		let f = |x: i32| vec![x.wrapping_mul(2)];
1311		bind::<VecBrand, _, _>(pure::<VecBrand, _>(a), f) == f(a)
1312	}
1313
1314	/// Tests the right identity law for Monad.
1315	#[quickcheck]
1316	fn monad_right_identity(m: Vec<i32>) -> bool {
1317		bind::<VecBrand, _, _>(m.clone(), pure::<VecBrand, _>) == m
1318	}
1319
1320	/// Tests the associativity law for Monad.
1321	#[quickcheck]
1322	fn monad_associativity(m: Vec<i32>) -> bool {
1323		let f = |x: i32| vec![x.wrapping_mul(2)];
1324		let g = |x: i32| vec![x.wrapping_add(1)];
1325		bind::<VecBrand, _, _>(bind::<VecBrand, _, _>(m.clone(), f), g)
1326			== bind::<VecBrand, _, _>(m, |x| bind::<VecBrand, _, _>(f(x), g))
1327	}
1328
1329	// Edge Cases
1330
1331	/// Tests `map` on an empty vector.
1332	#[test]
1333	fn map_empty() {
1334		assert_eq!(map::<VecBrand, _, _>(|x: i32| x + 1, vec![] as Vec<i32>), vec![] as Vec<i32>);
1335	}
1336
1337	/// Tests `bind` on an empty vector.
1338	#[test]
1339	fn bind_empty() {
1340		assert_eq!(
1341			bind::<VecBrand, _, _>(vec![] as Vec<i32>, |x: i32| vec![x + 1]),
1342			vec![] as Vec<i32>
1343		);
1344	}
1345
1346	/// Tests `bind` returning an empty vector.
1347	#[test]
1348	fn bind_returning_empty() {
1349		assert_eq!(
1350			bind::<VecBrand, _, _>(vec![1, 2, 3], |_| vec![] as Vec<i32>),
1351			vec![] as Vec<i32>
1352		);
1353	}
1354
1355	/// Tests `fold_right` on an empty vector.
1356	#[test]
1357	fn fold_right_empty() {
1358		assert_eq!(
1359			crate::classes::foldable::fold_right::<RcFnBrand, VecBrand, _, _>(
1360				|x: i32, acc| x + acc,
1361				0,
1362				vec![]
1363			),
1364			0
1365		);
1366	}
1367
1368	/// Tests `fold_left` on an empty vector.
1369	#[test]
1370	fn fold_left_empty() {
1371		assert_eq!(
1372			crate::classes::foldable::fold_left::<RcFnBrand, VecBrand, _, _>(
1373				|acc, x: i32| acc + x,
1374				0,
1375				vec![]
1376			),
1377			0
1378		);
1379	}
1380
1381	/// Tests `traverse` on an empty vector.
1382	#[test]
1383	fn traverse_empty() {
1384		use crate::brands::OptionBrand;
1385		assert_eq!(
1386			crate::classes::traversable::traverse::<VecBrand, _, _, OptionBrand>(
1387				|x: i32| Some(x + 1),
1388				vec![]
1389			),
1390			Some(vec![])
1391		);
1392	}
1393
1394	/// Tests `traverse` returning an empty vector.
1395	#[test]
1396	fn traverse_returning_empty() {
1397		use crate::brands::OptionBrand;
1398		assert_eq!(
1399			crate::classes::traversable::traverse::<VecBrand, _, _, OptionBrand>(
1400				|_: i32| None::<i32>,
1401				vec![1, 2, 3]
1402			),
1403			None
1404		);
1405	}
1406
1407	/// Tests `construct` with an empty tail.
1408	#[test]
1409	fn construct_empty_tail() {
1410		assert_eq!(VecBrand::construct(1, vec![]), vec![1]);
1411	}
1412
1413	/// Tests `deconstruct` on an empty slice.
1414	#[test]
1415	fn deconstruct_empty() {
1416		assert_eq!(VecBrand::deconstruct::<i32>(&[]), None);
1417	}
1418
1419	// ParFoldable Tests
1420
1421	/// Tests `par_fold_map` on an empty vector.
1422	#[test]
1423	fn par_fold_map_empty() {
1424		let v: Vec<i32> = vec![];
1425		let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1426		assert_eq!(par_fold_map::<ArcFnBrand, VecBrand, _, _>(f, v), "".to_string());
1427	}
1428
1429	/// Tests `par_fold_map` on a single element.
1430	#[test]
1431	fn par_fold_map_single() {
1432		let v = vec![1];
1433		let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1434		assert_eq!(par_fold_map::<ArcFnBrand, VecBrand, _, _>(f, v), "1".to_string());
1435	}
1436
1437	/// Tests `par_fold_map` on multiple elements.
1438	#[test]
1439	fn par_fold_map_multiple() {
1440		let v = vec![1, 2, 3];
1441		let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1442		assert_eq!(par_fold_map::<ArcFnBrand, VecBrand, _, _>(f, v), "123".to_string());
1443	}
1444
1445	/// Tests `par_fold_right` on multiple elements.
1446	#[test]
1447	fn par_fold_right_multiple() {
1448		let v = vec![1, 2, 3];
1449		let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
1450		assert_eq!(par_fold_right::<ArcFnBrand, VecBrand, _, _>(f, 0, v), 6);
1451	}
1452
1453	// Filterable Laws
1454
1455	/// Tests `filterMap identity ≡ compact`.
1456	#[quickcheck]
1457	fn filterable_filter_map_identity(x: Vec<Option<i32>>) -> bool {
1458		filter_map::<VecBrand, _, _>(identity, x.clone()) == compact::<VecBrand, _>(x)
1459	}
1460
1461	/// Tests `filterMap Just ≡ identity`.
1462	#[quickcheck]
1463	fn filterable_filter_map_just(x: Vec<i32>) -> bool {
1464		filter_map::<VecBrand, _, _>(Some, x.clone()) == x
1465	}
1466
1467	/// Tests `filterMap (l <=< r) ≡ filterMap l <<< filterMap r`.
1468	#[quickcheck]
1469	fn filterable_filter_map_composition(x: Vec<i32>) -> bool {
1470		let r = |i: i32| if i % 2 == 0 { Some(i) } else { None };
1471		let l = |i: i32| if i > 5 { Some(i) } else { None };
1472		let composed = |i| bind::<OptionBrand, _, _>(r(i), l);
1473
1474		filter_map::<VecBrand, _, _>(composed, x.clone())
1475			== filter_map::<VecBrand, _, _>(l, filter_map::<VecBrand, _, _>(r, x))
1476	}
1477
1478	/// Tests `filter ≡ filterMap <<< maybeBool`.
1479	#[quickcheck]
1480	fn filterable_filter_consistency(x: Vec<i32>) -> bool {
1481		let p = |i: i32| i % 2 == 0;
1482		let maybe_bool = |i| if p(i) { Some(i) } else { None };
1483
1484		filter::<VecBrand, _>(p, x.clone()) == filter_map::<VecBrand, _, _>(maybe_bool, x)
1485	}
1486
1487	/// Tests `partitionMap identity ≡ separate`.
1488	#[quickcheck]
1489	fn filterable_partition_map_identity(x: Vec<Result<i32, i32>>) -> bool {
1490		partition_map::<VecBrand, _, _, _>(identity, x.clone()) == separate::<VecBrand, _, _>(x)
1491	}
1492
1493	/// Tests `partitionMap Right ≡ identity` (on the right side).
1494	#[quickcheck]
1495	fn filterable_partition_map_right_identity(x: Vec<i32>) -> bool {
1496		let (_, oks) = partition_map::<VecBrand, _, _, _>(Ok::<_, i32>, x.clone());
1497		oks == x
1498	}
1499
1500	/// Tests `partitionMap Left ≡ identity` (on the left side).
1501	#[quickcheck]
1502	fn filterable_partition_map_left_identity(x: Vec<i32>) -> bool {
1503		let (errs, _) = partition_map::<VecBrand, _, _, _>(Err::<i32, _>, x.clone());
1504		errs == x
1505	}
1506
1507	/// Tests `f <<< partition ≡ partitionMap <<< eitherBool`.
1508	#[quickcheck]
1509	fn filterable_partition_consistency(x: Vec<i32>) -> bool {
1510		let p = |i: i32| i % 2 == 0;
1511		let either_bool = |i| if p(i) { Ok(i) } else { Err(i) };
1512
1513		let (not_satisfied, satisfied) = partition::<VecBrand, _>(p, x.clone());
1514		let (errs, oks) = partition_map::<VecBrand, _, _, _>(either_bool, x);
1515
1516		satisfied == oks && not_satisfied == errs
1517	}
1518
1519	// Witherable Laws
1520
1521	/// Tests `wither (pure <<< Just) ≡ pure`.
1522	#[quickcheck]
1523	fn witherable_identity(x: Vec<i32>) -> bool {
1524		wither::<VecBrand, OptionBrand, _, _>(|i| Some(Some(i)), x.clone()) == Some(x)
1525	}
1526
1527	/// Tests `wilt p ≡ map separate <<< traverse p`.
1528	#[quickcheck]
1529	fn witherable_wilt_consistency(x: Vec<i32>) -> bool {
1530		let p = |i: i32| Some(if i % 2 == 0 { Ok(i) } else { Err(i) });
1531
1532		let lhs = wilt::<VecBrand, OptionBrand, _, _, _>(p, x.clone());
1533		let rhs = crate::classes::functor::map::<OptionBrand, _, _>(
1534			separate::<VecBrand, _, _>,
1535			traverse::<VecBrand, _, _, OptionBrand>(p, x),
1536		);
1537
1538		lhs == rhs
1539	}
1540
1541	/// Tests `wither p ≡ map compact <<< traverse p`.
1542	#[quickcheck]
1543	fn witherable_wither_consistency(x: Vec<i32>) -> bool {
1544		let p = |i: i32| Some(if i % 2 == 0 { Some(i) } else { None });
1545
1546		let lhs = wither::<VecBrand, OptionBrand, _, _>(p, x.clone());
1547		let rhs = crate::classes::functor::map::<OptionBrand, _, _>(
1548			compact::<VecBrand, _>,
1549			traverse::<VecBrand, _, _, OptionBrand>(p, x),
1550		);
1551
1552		lhs == rhs
1553	}
1554
1555	// Alt Laws
1556
1557	/// Tests the associativity law for Alt.
1558	#[quickcheck]
1559	fn alt_associativity(
1560		x: Vec<i32>,
1561		y: Vec<i32>,
1562		z: Vec<i32>,
1563	) -> bool {
1564		alt::<VecBrand, _>(alt::<VecBrand, _>(x.clone(), y.clone()), z.clone())
1565			== alt::<VecBrand, _>(x, alt::<VecBrand, _>(y, z))
1566	}
1567
1568	/// Tests the distributivity law for Alt.
1569	#[quickcheck]
1570	fn alt_distributivity(
1571		x: Vec<i32>,
1572		y: Vec<i32>,
1573	) -> bool {
1574		let f = |i: i32| i.wrapping_mul(2).wrapping_add(1);
1575		map::<VecBrand, _, _>(f, alt::<VecBrand, _>(x.clone(), y.clone()))
1576			== alt::<VecBrand, _>(map::<VecBrand, _, _>(f, x), map::<VecBrand, _, _>(f, y))
1577	}
1578
1579	// Plus Laws
1580
1581	/// Tests the left identity law for Plus.
1582	#[quickcheck]
1583	fn plus_left_identity(x: Vec<i32>) -> bool {
1584		alt::<VecBrand, _>(plus_empty::<VecBrand, i32>(), x.clone()) == x
1585	}
1586
1587	/// Tests the right identity law for Plus.
1588	#[quickcheck]
1589	fn plus_right_identity(x: Vec<i32>) -> bool {
1590		alt::<VecBrand, _>(x.clone(), plus_empty::<VecBrand, i32>()) == x
1591	}
1592
1593	/// Tests the annihilation law for Plus.
1594	#[test]
1595	fn plus_annihilation() {
1596		let f = |i: i32| i.wrapping_mul(2);
1597		assert_eq!(
1598			map::<VecBrand, _, _>(f, plus_empty::<VecBrand, i32>()),
1599			plus_empty::<VecBrand, i32>(),
1600		);
1601	}
1602
1603	// Compactable Laws (Plus-dependent)
1604
1605	/// Tests the functor identity law for Compactable.
1606	#[quickcheck]
1607	fn compactable_functor_identity(fa: Vec<i32>) -> bool {
1608		compact::<VecBrand, _>(map::<VecBrand, _, _>(Some, fa.clone())) == fa
1609	}
1610
1611	/// Tests the Plus annihilation (empty) law for Compactable.
1612	#[test]
1613	fn compactable_plus_annihilation_empty() {
1614		assert_eq!(
1615			compact::<VecBrand, _>(plus_empty::<VecBrand, Option<i32>>()),
1616			plus_empty::<VecBrand, i32>(),
1617		);
1618	}
1619
1620	/// Tests the Plus annihilation (map) law for Compactable.
1621	#[quickcheck]
1622	fn compactable_plus_annihilation_map(xs: Vec<i32>) -> bool {
1623		compact::<VecBrand, _>(map::<VecBrand, _, _>(|_: i32| None::<i32>, xs))
1624			== plus_empty::<VecBrand, i32>()
1625	}
1626
1627	// Edge Cases
1628
1629	/// Tests `compact` on an empty vector.
1630	#[test]
1631	fn compact_empty() {
1632		assert_eq!(compact::<VecBrand, i32>(vec![] as Vec<Option<i32>>), vec![] as Vec<i32>);
1633	}
1634
1635	/// Tests `compact` on a vector with `None`.
1636	#[test]
1637	fn compact_with_none() {
1638		assert_eq!(compact::<VecBrand, i32>(vec![Some(1), None, Some(2)]), vec![1, 2]);
1639	}
1640
1641	/// Tests `separate` on an empty vector.
1642	#[test]
1643	fn separate_empty() {
1644		let (errs, oks) = separate::<VecBrand, i32, i32>(vec![] as Vec<Result<i32, i32>>);
1645		assert_eq!(oks, vec![] as Vec<i32>);
1646		assert_eq!(errs, vec![] as Vec<i32>);
1647	}
1648
1649	/// Tests `separate` on a vector with `Ok` and `Err`.
1650	#[test]
1651	fn separate_mixed() {
1652		let (errs, oks) = separate::<VecBrand, i32, i32>(vec![Ok(1), Err(2), Ok(3)]);
1653		assert_eq!(oks, vec![1, 3]);
1654		assert_eq!(errs, vec![2]);
1655	}
1656
1657	/// Tests `partition_map` on an empty vector.
1658	#[test]
1659	fn partition_map_empty() {
1660		let (errs, oks) =
1661			partition_map::<VecBrand, i32, i32, _>(|x: i32| Ok::<i32, i32>(x), vec![]);
1662		assert_eq!(oks, vec![] as Vec<i32>);
1663		assert_eq!(errs, vec![] as Vec<i32>);
1664	}
1665
1666	/// Tests `partition` on an empty vector.
1667	#[test]
1668	fn partition_empty() {
1669		let (not_satisfied, satisfied) = partition::<VecBrand, i32>(|x: i32| x > 0, vec![]);
1670		assert_eq!(satisfied, vec![] as Vec<i32>);
1671		assert_eq!(not_satisfied, vec![] as Vec<i32>);
1672	}
1673
1674	/// Tests `filter_map` on an empty vector.
1675	#[test]
1676	fn filter_map_empty() {
1677		assert_eq!(filter_map::<VecBrand, i32, _>(|x: i32| Some(x), vec![]), vec![] as Vec<i32>);
1678	}
1679
1680	/// Tests `filter` on an empty vector.
1681	#[test]
1682	fn filter_empty() {
1683		assert_eq!(filter::<VecBrand, i32>(|x: i32| x > 0, vec![]), vec![] as Vec<i32>);
1684	}
1685
1686	/// Tests `wilt` on an empty vector.
1687	#[test]
1688	fn wilt_empty() {
1689		let res = wilt::<VecBrand, OptionBrand, _, _, _>(|x: i32| Some(Ok::<i32, i32>(x)), vec![]);
1690		assert_eq!(res, Some((vec![], vec![])));
1691	}
1692
1693	/// Tests `wither` on an empty vector.
1694	#[test]
1695	fn wither_empty() {
1696		let res = wither::<VecBrand, OptionBrand, _, _>(|x: i32| Some(Some(x)), vec![]);
1697		assert_eq!(res, Some(vec![]));
1698	}
1699
1700	// ParFoldable Laws
1701
1702	/// Verifies that `par_fold_map` correctly sums a large vector (100,000 elements).
1703	#[test]
1704	fn test_large_vector_par_fold_map() {
1705		use crate::types::Additive;
1706
1707		let xs: Vec<i32> = (0 .. 100000).collect();
1708		let f_par = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| Additive(x as i64));
1709		let res = par_fold_map::<ArcFnBrand, VecBrand, _, _>(f_par, xs);
1710		assert_eq!(res, Additive(4999950000));
1711	}
1712
1713	/// Property: parallel `par_fold_map` produces the same result as sequential `fold_map`.
1714	#[quickcheck]
1715	fn prop_par_fold_map_equals_fold_map(xs: Vec<i32>) -> bool {
1716		use crate::types::Additive;
1717
1718		let f_seq = |x: i32| Additive(x as i64);
1719		let f_par = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| Additive(x as i64));
1720
1721		let seq_res =
1722			crate::classes::foldable::fold_map::<ArcFnBrand, VecBrand, _, _>(f_seq, xs.clone());
1723		let par_res = par_fold_map::<ArcFnBrand, VecBrand, _, _>(f_par, xs);
1724
1725		seq_res == par_res
1726	}
1727
1728	/// Property: parallel `par_fold_right` produces the same result as sequential `fold_right`.
1729	#[quickcheck]
1730	fn prop_par_fold_right_equals_fold_right(xs: Vec<i32>) -> bool {
1731		let f_seq = |a: i32, b: i32| a.wrapping_add(b);
1732		let f_par =
1733			send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a.wrapping_add(b));
1734		let init = 0;
1735
1736		let seq_res = crate::classes::foldable::fold_right::<ArcFnBrand, VecBrand, _, _>(
1737			f_seq,
1738			init,
1739			xs.clone(),
1740		);
1741		let par_res = par_fold_right::<ArcFnBrand, VecBrand, _, _>(f_par, init, xs);
1742
1743		seq_res == par_res
1744	}
1745
1746	/// Property: `par_fold_map` on an empty vector returns the Monoid's empty value.
1747	#[quickcheck]
1748	fn prop_par_fold_map_empty_is_empty(xs: Vec<i32>) -> bool {
1749		use crate::types::Additive;
1750
1751		if !xs.is_empty() {
1752			return true;
1753		}
1754
1755		let f_par = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| Additive(x as i64));
1756		let par_res = par_fold_map::<ArcFnBrand, VecBrand, _, _>(f_par, xs);
1757
1758		par_res == empty::<Additive<i64>>()
1759	}
1760
1761	/// Property: `par_fold_map` is deterministic.
1762	#[quickcheck]
1763	fn prop_par_fold_map_deterministic(xs: Vec<i32>) -> bool {
1764		use crate::types::Additive;
1765
1766		let f_par = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| Additive(x as i64));
1767
1768		let res1 = par_fold_map::<ArcFnBrand, VecBrand, _, _>(f_par.clone(), xs.clone());
1769		let res2 = par_fold_map::<ArcFnBrand, VecBrand, _, _>(f_par, xs);
1770		res1 == res2
1771	}
1772}