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