fp_library/types/
vec.rs

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