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