Skip to main content

fp_library/types/
vec.rs

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