Skip to main content

fp_library/types/
pair.rs

1//! Two-value container with [`Bifunctor`](crate::classes::Bifunctor) and dual [`Functor`](crate::classes::Functor) instances.
2//!
3//! Can be used as a bifunctor over both values, or as a functor/monad by fixing either the first value [`PairFirstAppliedBrand`](crate::brands::PairFirstAppliedBrand) or second value [`PairSecondAppliedBrand`](crate::brands::PairSecondAppliedBrand).
4
5#[fp_macros::document_module]
6mod inner {
7	use {
8		crate::{
9			Apply,
10			brands::{
11				PairBrand,
12				PairFirstAppliedBrand,
13				PairSecondAppliedBrand,
14			},
15			classes::{
16				Applicative,
17				ApplyFirst,
18				ApplySecond,
19				Bifoldable,
20				Bifunctor,
21				Bitraversable,
22				CloneableFn,
23				Foldable,
24				Functor,
25				Lift,
26				Monoid,
27				ParFoldable,
28				Pointed,
29				Semiapplicative,
30				Semigroup,
31				Semimonad,
32				SendCloneableFn,
33				Traversable,
34			},
35			impl_kind,
36			kinds::*,
37		},
38		fp_macros::*,
39	};
40
41	/// Wraps two values.
42	///
43	/// A simple tuple struct that holds two values of potentially different types.
44	///
45	/// ### Higher-Kinded Type Representation
46	///
47	/// This type has multiple higher-kinded representations:
48	/// - [`PairBrand`](crate::brands::PairBrand): fully polymorphic over both values (bifunctor).
49	/// - [`PairFirstAppliedBrand<First>`](crate::brands::PairFirstAppliedBrand): the first value type is fixed, polymorphic over the second (functor over second).
50	/// - [`PairSecondAppliedBrand<Second>`](crate::brands::PairSecondAppliedBrand): the second value type is fixed, polymorphic over the first (functor over first).
51	///
52	/// ### Serialization
53	///
54	/// This type supports serialization and deserialization via [`serde`](https://serde.rs) when the `serde` feature is enabled.
55	#[document_type_parameters("The type of the first value.", "The type of the second value.")]
56	///
57	#[document_fields("The first value.", "The second value.")]
58	///
59	#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
60	#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
61	pub struct Pair<First, Second>(pub First, pub Second);
62
63	impl_kind! {
64		for PairBrand {
65			type Of<First,Second> = Pair<First, Second>;
66		}
67	}
68
69	impl_kind! {
70		for PairBrand {
71			type Of<'a, First: 'a, Second: 'a>: 'a = Pair<First, Second>;
72		}
73	}
74
75	#[document_type_parameters("The type of the first value.", "The type of the second value.")]
76	#[document_parameters("The pair instance.")]
77	impl<First, Second> Pair<First, Second> {
78		/// Maps functions over both values in the pair.
79		///
80		/// See [`Bifunctor::bimap`] for the type class version.
81		#[document_signature]
82		///
83		#[document_type_parameters(
84			"The type of the mapped first value.",
85			"The type of the mapped second value."
86		)]
87		///
88		#[document_parameters(
89			"The function to apply to the first value.",
90			"The function to apply to the second value."
91		)]
92		///
93		#[document_returns("A new pair containing the mapped values.")]
94		///
95		#[document_examples]
96		///
97		/// ```
98		/// use fp_library::types::*;
99		///
100		/// let x = Pair(1, 5);
101		/// assert_eq!(x.bimap(|a| a + 1, |b| b * 2), Pair(2, 10));
102		/// ```
103		pub fn bimap<B, D>(
104			self,
105			f: impl FnOnce(First) -> B,
106			g: impl FnOnce(Second) -> D,
107		) -> Pair<B, D> {
108			Pair(f(self.0), g(self.1))
109		}
110
111		/// Maps a function over the first value in the pair.
112		///
113		/// See [`Bifunctor::bimap`] for the type class version.
114		#[document_signature]
115		///
116		#[document_type_parameters("The type of the mapped first value.")]
117		///
118		#[document_parameters("The function to apply to the first value.")]
119		///
120		#[document_returns("A new pair with the transformed first value.")]
121		///
122		#[document_examples]
123		///
124		/// ```
125		/// use fp_library::types::*;
126		///
127		/// let x = Pair(1, 5);
128		/// assert_eq!(x.map_first(|a| a + 1), Pair(2, 5));
129		/// ```
130		pub fn map_first<B>(
131			self,
132			f: impl FnOnce(First) -> B,
133		) -> Pair<B, Second> {
134			Pair(f(self.0), self.1)
135		}
136
137		/// Maps a function over the second value in the pair.
138		///
139		/// See [`Bifunctor::bimap`] for the type class version.
140		#[document_signature]
141		///
142		#[document_type_parameters("The type of the mapped second value.")]
143		///
144		#[document_parameters("The function to apply to the second value.")]
145		///
146		#[document_returns("A new pair with the transformed second value.")]
147		///
148		#[document_examples]
149		///
150		/// ```
151		/// use fp_library::types::*;
152		///
153		/// let x = Pair(1, 5);
154		/// assert_eq!(x.map_second(|b| b * 2), Pair(1, 10));
155		/// ```
156		pub fn map_second<D>(
157			self,
158			g: impl FnOnce(Second) -> D,
159		) -> Pair<First, D> {
160			Pair(self.0, g(self.1))
161		}
162
163		/// Folds both values into a single result.
164		///
165		/// Applies two functions to the first and second values respectively,
166		/// then combines the results using `FnOnce`.
167		#[document_signature]
168		///
169		#[document_type_parameters("The result type.")]
170		///
171		#[document_parameters(
172			"The function to apply to the first value.",
173			"The function to apply to the second value.",
174			"The function to combine the results."
175		)]
176		///
177		#[document_returns("The combined result.")]
178		///
179		#[document_examples]
180		///
181		/// ```
182		/// use fp_library::types::*;
183		///
184		/// let x = Pair(1, 2);
185		/// let y = x.fold(|a| a.to_string(), |b| b.to_string(), |a, b| format!("{a},{b}"));
186		/// assert_eq!(y, "1,2");
187		/// ```
188		pub fn fold<C>(
189			self,
190			f: impl FnOnce(First) -> C,
191			g: impl FnOnce(Second) -> C,
192			combine: impl FnOnce(C, C) -> C,
193		) -> C {
194			combine(f(self.0), g(self.1))
195		}
196
197		/// Folds the pair from right to left using two step functions.
198		///
199		/// See [`Bifoldable::bi_fold_right`] for the type class version.
200		#[document_signature]
201		///
202		#[document_type_parameters("The accumulator type.")]
203		///
204		#[document_parameters(
205			"The step function for the first value.",
206			"The step function for the second value.",
207			"The initial accumulator."
208		)]
209		///
210		#[document_returns("The result of folding: `f(first, g(second, z))`.")]
211		///
212		#[document_examples]
213		///
214		/// ```
215		/// use fp_library::types::*;
216		///
217		/// let x = Pair(3, 5);
218		/// assert_eq!(x.bi_fold_right(|a, acc| acc - a, |b, acc| acc + b, 0), 2);
219		/// ```
220		pub fn bi_fold_right<C>(
221			self,
222			f: impl FnOnce(First, C) -> C,
223			g: impl FnOnce(Second, C) -> C,
224			z: C,
225		) -> C {
226			f(self.0, g(self.1, z))
227		}
228
229		/// Folds the pair from left to right using two step functions.
230		///
231		/// See [`Bifoldable::bi_fold_left`] for the type class version.
232		#[document_signature]
233		///
234		#[document_type_parameters("The accumulator type.")]
235		///
236		#[document_parameters(
237			"The step function for the first value.",
238			"The step function for the second value.",
239			"The initial accumulator."
240		)]
241		///
242		#[document_returns("The result of folding: `g(f(z, first), second)`.")]
243		///
244		#[document_examples]
245		///
246		/// ```
247		/// use fp_library::types::*;
248		///
249		/// let x = Pair(3, 5);
250		/// assert_eq!(x.bi_fold_left(|acc, a| acc - a, |acc, b| acc + b, 0), 2);
251		/// ```
252		pub fn bi_fold_left<C>(
253			self,
254			f: impl FnOnce(C, First) -> C,
255			g: impl FnOnce(C, Second) -> C,
256			z: C,
257		) -> C {
258			g(f(z, self.0), self.1)
259		}
260
261		/// Maps both values to a monoid and combines the results.
262		///
263		/// See [`Bifoldable::bi_fold_map`] for the type class version.
264		#[document_signature]
265		///
266		#[document_type_parameters("The monoid type.")]
267		///
268		#[document_parameters(
269			"The function mapping the first value to the monoid.",
270			"The function mapping the second value to the monoid."
271		)]
272		///
273		#[document_returns("The combined monoid value.")]
274		///
275		#[document_examples]
276		///
277		/// ```
278		/// use fp_library::types::*;
279		///
280		/// let x = Pair(3, 5);
281		/// assert_eq!(x.bi_fold_map(|a: i32| a.to_string(), |b: i32| b.to_string()), "35".to_string());
282		/// ```
283		pub fn bi_fold_map<M: Semigroup>(
284			self,
285			f: impl FnOnce(First) -> M,
286			g: impl FnOnce(Second) -> M,
287		) -> M {
288			Semigroup::append(f(self.0), g(self.1))
289		}
290	}
291
292	#[document_type_parameters(
293		"The lifetime of the values.",
294		"The type of the first value.",
295		"The type of the second value."
296	)]
297	#[document_parameters("The pair instance.")]
298	impl<'a, First: 'a, Second: 'a> Pair<First, Second> {
299		/// Traverses the pair with two effectful functions.
300		///
301		/// See [`Bitraversable::bi_traverse`] for the type class version.
302		#[document_signature]
303		///
304		#[document_type_parameters(
305			"The output type for the first value.",
306			"The output type for the second value.",
307			"The applicative context."
308		)]
309		///
310		#[document_parameters(
311			"The function for the first value.",
312			"The function for the second value."
313		)]
314		///
315		#[document_returns("A pair of the transformed values wrapped in the applicative context.")]
316		///
317		#[document_examples]
318		///
319		/// ```
320		/// use fp_library::{
321		/// 	brands::*,
322		/// 	types::*,
323		/// };
324		///
325		/// let x = Pair(3, 5);
326		/// let y = x.bi_traverse::<_, _, OptionBrand>(|a| Some(a + 1), |b| Some(b * 2));
327		/// assert_eq!(y, Some(Pair(4, 10)));
328		/// ```
329		pub fn bi_traverse<C: 'a + Clone, D: 'a + Clone, F: Applicative>(
330			self,
331			f: impl Fn(First) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) + 'a,
332			g: impl Fn(Second) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>) + 'a,
333		) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Pair<C, D>>)
334		where
335			Pair<C, D>: Clone, {
336			F::lift2(|c, d| Pair(c, d), f(self.0), g(self.1))
337		}
338	}
339
340	#[document_type_parameters("The type of the first value.", "The type of the second value.")]
341	#[document_parameters("The pair instance.")]
342	impl<First: Semigroup, Second> Pair<First, Second> {
343		/// Chains a computation over the second value, combining first values via their semigroup.
344		///
345		/// See [`Semimonad::bind`] for the type class version
346		/// (via [`PairFirstAppliedBrand`]).
347		#[document_signature]
348		///
349		#[document_type_parameters("The type of the new second value.")]
350		///
351		#[document_parameters("The function to apply to the second value.")]
352		///
353		#[document_returns(
354			"A new pair where the first values are combined and the second value is transformed."
355		)]
356		///
357		#[document_examples]
358		///
359		/// ```
360		/// use fp_library::types::*;
361		///
362		/// assert_eq!(
363		/// 	Pair("a".to_string(), 5).bind(|x| Pair("b".to_string(), x * 2)),
364		/// 	Pair("ab".to_string(), 10)
365		/// );
366		/// ```
367		pub fn bind<C>(
368			self,
369			f: impl FnOnce(Second) -> Pair<First, C>,
370		) -> Pair<First, C> {
371			let Pair(first, second) = self;
372			let Pair(next_first, next_second) = f(second);
373			Pair(Semigroup::append(first, next_first), next_second)
374		}
375	}
376
377	#[document_type_parameters("The type of the first value.", "The type of the second value.")]
378	#[document_parameters("The pair instance.")]
379	impl<First, Second: Semigroup> Pair<First, Second> {
380		/// Chains a computation over the first value, combining second values via their semigroup.
381		///
382		/// See [`Semimonad::bind`] for the type class version
383		/// (via [`PairSecondAppliedBrand`]).
384		#[document_signature]
385		///
386		#[document_type_parameters("The type of the new first value.")]
387		///
388		#[document_parameters("The function to apply to the first value.")]
389		///
390		#[document_returns(
391			"A new pair where the first value is transformed and the second values are combined."
392		)]
393		///
394		#[document_examples]
395		///
396		/// ```
397		/// use fp_library::types::*;
398		///
399		/// assert_eq!(
400		/// 	Pair(5, "a".to_string()).bind_first(|x| Pair(x * 2, "b".to_string())),
401		/// 	Pair(10, "ab".to_string())
402		/// );
403		/// ```
404		pub fn bind_first<C>(
405			self,
406			f: impl FnOnce(First) -> Pair<C, Second>,
407		) -> Pair<C, Second> {
408			let Pair(first, second) = self;
409			let Pair(next_first, next_second) = f(first);
410			Pair(next_first, Semigroup::append(second, next_second))
411		}
412	}
413
414	impl Bifunctor for PairBrand {
415		/// Maps functions over the values in the pair.
416		///
417		/// This method applies one function to the first value and another to the second value.
418		#[document_signature]
419		///
420		#[document_type_parameters(
421			"The lifetime of the values.",
422			"The type of the first value.",
423			"The type of the mapped first value.",
424			"The type of the second value.",
425			"The type of the mapped second value."
426		)]
427		///
428		#[document_parameters(
429			"The function to apply to the first value.",
430			"The function to apply to the second value.",
431			"The pair to map over."
432		)]
433		///
434		#[document_returns("A new pair containing the mapped values.")]
435		#[document_examples]
436		///
437		/// ```
438		/// use fp_library::{
439		/// 	brands::*,
440		/// 	classes::bifunctor::*,
441		/// 	functions::*,
442		/// 	types::*,
443		/// };
444		///
445		/// let x = Pair(1, 5);
446		/// assert_eq!(bimap::<PairBrand, _, _, _, _>(|a| a + 1, |b| b * 2, x), Pair(2, 10));
447		/// ```
448		fn bimap<'a, A: 'a, B: 'a, C: 'a, D: 'a>(
449			f: impl Fn(A) -> B + 'a,
450			g: impl Fn(C) -> D + 'a,
451			p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, C>),
452		) -> Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, B, D>) {
453			p.bimap(f, g)
454		}
455	}
456
457	impl Bifoldable for PairBrand {
458		/// Folds the pair from right to left using two step functions.
459		///
460		/// Folds `Pair(a, b)` as `f(a, g(b, z))`.
461		#[document_signature]
462		///
463		#[document_type_parameters(
464			"The lifetime of the values.",
465			"The brand of the cloneable function to use.",
466			"The type of the first value.",
467			"The type of the second value.",
468			"The accumulator type."
469		)]
470		///
471		#[document_parameters(
472			"The step function for the first value.",
473			"The step function for the second value.",
474			"The initial accumulator.",
475			"The pair to fold."
476		)]
477		///
478		#[document_returns("`f(a, g(b, z))`.")]
479		#[document_examples]
480		///
481		/// ```
482		/// use fp_library::{
483		/// 	brands::*,
484		/// 	functions::*,
485		/// 	types::*,
486		/// };
487		///
488		/// let x = Pair(3, 5);
489		/// assert_eq!(
490		/// 	bi_fold_right::<RcFnBrand, PairBrand, _, _, _>(|a, acc| acc - a, |b, acc| acc + b, 0, x,),
491		/// 	2
492		/// );
493		/// ```
494		fn bi_fold_right<'a, FnBrand: CloneableFn + 'a, A: 'a + Clone, B: 'a + Clone, C: 'a>(
495			f: impl Fn(A, C) -> C + 'a,
496			g: impl Fn(B, C) -> C + 'a,
497			z: C,
498			p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
499		) -> C {
500			p.bi_fold_right(f, g, z)
501		}
502
503		/// Folds the pair from left to right using two step functions.
504		///
505		/// Folds `Pair(a, b)` as `g(f(z, a), b)`.
506		#[document_signature]
507		///
508		#[document_type_parameters(
509			"The lifetime of the values.",
510			"The brand of the cloneable function to use.",
511			"The type of the first value.",
512			"The type of the second value.",
513			"The accumulator type."
514		)]
515		///
516		#[document_parameters(
517			"The step function for the first value.",
518			"The step function for the second value.",
519			"The initial accumulator.",
520			"The pair to fold."
521		)]
522		///
523		#[document_returns("`g(f(z, a), b)`.")]
524		#[document_examples]
525		///
526		/// ```
527		/// use fp_library::{
528		/// 	brands::*,
529		/// 	functions::*,
530		/// 	types::*,
531		/// };
532		///
533		/// let x = Pair(3, 5);
534		/// assert_eq!(
535		/// 	bi_fold_left::<RcFnBrand, PairBrand, _, _, _>(|acc, a| acc - a, |acc, b| acc + b, 0, x,),
536		/// 	2
537		/// );
538		/// ```
539		fn bi_fold_left<'a, FnBrand: CloneableFn + 'a, A: 'a + Clone, B: 'a + Clone, C: 'a>(
540			f: impl Fn(C, A) -> C + 'a,
541			g: impl Fn(C, B) -> C + 'a,
542			z: C,
543			p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
544		) -> C {
545			p.bi_fold_left(f, g, z)
546		}
547
548		/// Maps both values to a monoid and combines the results.
549		///
550		/// Computes `Semigroup::append(f(a), g(b))` for `Pair(a, b)`.
551		#[document_signature]
552		///
553		#[document_type_parameters(
554			"The lifetime of the values.",
555			"The brand of the cloneable function to use.",
556			"The type of the first value.",
557			"The type of the second value.",
558			"The monoid type."
559		)]
560		///
561		#[document_parameters(
562			"The function mapping the first value to the monoid.",
563			"The function mapping the second value to the monoid.",
564			"The pair to fold."
565		)]
566		///
567		#[document_returns("`Semigroup::append(f(a), g(b))`.")]
568		#[document_examples]
569		///
570		/// ```
571		/// use fp_library::{
572		/// 	brands::*,
573		/// 	functions::*,
574		/// 	types::*,
575		/// };
576		///
577		/// assert_eq!(
578		/// 	bi_fold_map::<RcFnBrand, PairBrand, _, _, _>(
579		/// 		|a: i32| a.to_string(),
580		/// 		|b: i32| b.to_string(),
581		/// 		Pair(3, 5),
582		/// 	),
583		/// 	"35".to_string()
584		/// );
585		/// ```
586		fn bi_fold_map<'a, FnBrand: CloneableFn + 'a, A: 'a + Clone, B: 'a + Clone, M>(
587			f: impl Fn(A) -> M + 'a,
588			g: impl Fn(B) -> M + 'a,
589			p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
590		) -> M
591		where
592			M: Monoid + 'a, {
593			p.bi_fold_map(f, g)
594		}
595	}
596
597	impl Bitraversable for PairBrand {
598		/// Traverses the pair with two effectful functions.
599		///
600		/// Applies `f` to the first value and `g` to the second value,
601		/// combining the effects via `lift2`.
602		#[document_signature]
603		///
604		#[document_type_parameters(
605			"The lifetime of the values.",
606			"The type of the first value.",
607			"The type of the second value.",
608			"The output type for the first value.",
609			"The output type for the second value.",
610			"The applicative context."
611		)]
612		///
613		#[document_parameters(
614			"The function applied to the first value.",
615			"The function applied to the second value.",
616			"The pair to traverse."
617		)]
618		///
619		#[document_returns("`lift2(Pair, f(a), g(b))`.")]
620		#[document_examples]
621		///
622		/// ```
623		/// use fp_library::{
624		/// 	brands::*,
625		/// 	functions::*,
626		/// 	types::*,
627		/// };
628		///
629		/// let x = Pair(3, 5);
630		/// assert_eq!(
631		/// 	bi_traverse::<PairBrand, _, _, _, _, OptionBrand>(
632		/// 		|a: i32| Some(a + 1),
633		/// 		|b: i32| Some(b * 2),
634		/// 		x,
635		/// 	),
636		/// 	Some(Pair(4, 10))
637		/// );
638		/// ```
639		fn bi_traverse<
640			'a,
641			A: 'a + Clone,
642			B: 'a + Clone,
643			C: 'a + Clone,
644			D: 'a + Clone,
645			F: Applicative,
646		>(
647			f: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) + 'a,
648			g: impl Fn(B) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, D>) + 'a,
649			p: Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, A, B>),
650		) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<Self as Kind!( type Of<'a, A: 'a, B: 'a>: 'a; )>::Of<'a, C, D>)>)
651		{
652			p.bi_traverse::<C, D, F>(f, g)
653		}
654	}
655
656	// PairFirstAppliedBrand<First> (Functor over Second)
657
658	impl_kind! {
659		#[document_type_parameters("The type of the first value in the pair.")]
660		impl<First: 'static> for PairFirstAppliedBrand<First> {
661			type Of<'a, A: 'a>: 'a = Pair<First, A>;
662		}
663	}
664
665	#[document_type_parameters("The type of the first value in the pair.")]
666	impl<First: 'static> Functor for PairFirstAppliedBrand<First> {
667		/// Maps a function over the second value in the pair.
668		///
669		/// This method applies a function to the second value inside the pair, producing a new pair with the transformed second value. The first value remains unchanged.
670		#[document_signature]
671		///
672		#[document_type_parameters(
673			"The lifetime of the values.",
674			"The type of the second value.",
675			"The type of the result of applying the function."
676		)]
677		///
678		#[document_parameters(
679			"The function to apply to the second value.",
680			"The pair to map over."
681		)]
682		///
683		#[document_returns(
684			"A new pair containing the result of applying the function to the second value."
685		)]
686		#[document_examples]
687		///
688		/// ```
689		/// use fp_library::{
690		/// 	brands::*,
691		/// 	functions::*,
692		/// 	types::*,
693		/// };
694		///
695		/// assert_eq!(map::<PairFirstAppliedBrand<_>, _, _>(|x: i32| x * 2, Pair(1, 5)), Pair(1, 10));
696		/// ```
697		fn map<'a, A: 'a, B: 'a>(
698			func: impl Fn(A) -> B + 'a,
699			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
700		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
701			fa.map_second(func)
702		}
703	}
704
705	#[document_type_parameters("The type of the first value in the pair.")]
706	impl<First: Clone + 'static> Lift for PairFirstAppliedBrand<First>
707	where
708		First: Semigroup,
709	{
710		/// Lifts a binary function into the pair context (over second).
711		///
712		/// This method lifts a binary function to operate on the second values within the pair context. The first values are combined using their `Semigroup` implementation.
713		#[document_signature]
714		///
715		#[document_type_parameters(
716			"The lifetime of the values.",
717			"The type of the first second value.",
718			"The type of the second second value.",
719			"The type of the result second value."
720		)]
721		///
722		#[document_parameters(
723			"The binary function to apply to the second values.",
724			"The first pair.",
725			"The second pair."
726		)]
727		///
728		#[document_returns(
729			"A new pair where the first values are combined using `Semigroup::append` and the second values are combined using `f`."
730		)]
731		#[document_examples]
732		///
733		/// ```
734		/// use fp_library::{
735		/// 	brands::*,
736		/// 	functions::*,
737		/// 	types::*,
738		/// };
739		///
740		/// assert_eq!(
741		/// 	lift2::<PairFirstAppliedBrand<String>, _, _, _>(
742		/// 		|x, y| x + y,
743		/// 		Pair("a".to_string(), 1),
744		/// 		Pair("b".to_string(), 2)
745		/// 	),
746		/// 	Pair("ab".to_string(), 3)
747		/// );
748		/// ```
749		fn lift2<'a, A, B, C>(
750			func: impl Fn(A, B) -> C + 'a,
751			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
752			fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
753		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
754		where
755			A: Clone + 'a,
756			B: Clone + 'a,
757			C: 'a, {
758			let Pair(fa_first, fa_second) = fa;
759			let Pair(fb_first, fb_second) = fb;
760			Pair(Semigroup::append(fa_first, fb_first), func(fa_second, fb_second))
761		}
762	}
763
764	#[document_type_parameters("The type of the first value in the pair.")]
765	impl<First: Clone + 'static> Pointed for PairFirstAppliedBrand<First>
766	where
767		First: Monoid,
768	{
769		/// Wraps a value in a pair (with empty first).
770		///
771		/// This method wraps a value in a pair, using the `Monoid::empty()` value for the first element.
772		#[document_signature]
773		///
774		#[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
775		///
776		#[document_parameters("The value to wrap.")]
777		///
778		#[document_returns("A pair containing the empty value of the first type and `a`.")]
779		///
780		#[document_examples]
781		///
782		/// ```
783		/// use fp_library::{
784		/// 	brands::*,
785		/// 	functions::*,
786		/// 	types::*,
787		/// };
788		///
789		/// assert_eq!(pure::<PairFirstAppliedBrand<String>, _>(5), Pair("".to_string(), 5));
790		/// ```
791		fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
792			Pair(Monoid::empty(), a)
793		}
794	}
795
796	#[document_type_parameters("The type of the first value in the pair.")]
797	impl<First: Clone + Semigroup + 'static> ApplyFirst for PairFirstAppliedBrand<First> {}
798
799	#[document_type_parameters("The type of the first value in the pair.")]
800	impl<First: Clone + Semigroup + 'static> ApplySecond for PairFirstAppliedBrand<First> {}
801
802	#[document_type_parameters("The type of the first value in the pair.")]
803	impl<First: Clone + 'static> Semiapplicative for PairFirstAppliedBrand<First>
804	where
805		First: Semigroup,
806	{
807		/// Applies a wrapped function to a wrapped value (over second).
808		///
809		/// This method applies a function wrapped in a pair to a value wrapped in a pair. The first values are combined using their `Semigroup` implementation.
810		#[document_signature]
811		///
812		#[document_type_parameters(
813			"The lifetime of the values.",
814			"The brand of the cloneable function wrapper.",
815			"The type of the input value.",
816			"The type of the output value."
817		)]
818		///
819		#[document_parameters(
820			"The pair containing the function.",
821			"The pair containing the value."
822		)]
823		///
824		#[document_returns(
825			"A new pair where the first values are combined and the function is applied to the second value."
826		)]
827		#[document_examples]
828		///
829		/// ```
830		/// use fp_library::{
831		/// 	brands::*,
832		/// 	functions::*,
833		/// 	types::*,
834		/// };
835		///
836		/// let f = Pair("a".to_string(), cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2));
837		/// assert_eq!(
838		/// 	apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(f, Pair("b".to_string(), 5)),
839		/// 	Pair("ab".to_string(), 10)
840		/// );
841		/// ```
842		fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
843			ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
844			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
845		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
846			Pair(Semigroup::append(ff.0, fa.0), ff.1(fa.1))
847		}
848	}
849
850	#[document_type_parameters("The type of the first value in the pair.")]
851	impl<First: Clone + 'static> Semimonad for PairFirstAppliedBrand<First>
852	where
853		First: Semigroup,
854	{
855		/// Chains pair computations (over second).
856		///
857		/// This method chains two computations, where the second computation depends on the result of the first. The first values are combined using their `Semigroup` implementation.
858		#[document_signature]
859		///
860		#[document_type_parameters(
861			"The lifetime of the values.",
862			"The type of the result of the first computation.",
863			"The type of the result of the second computation."
864		)]
865		///
866		#[document_parameters("The first pair.", "The function to apply to the second value.")]
867		///
868		#[document_returns("A new pair where the first values are combined.")]
869		///
870		#[document_examples]
871		///
872		/// ```
873		/// use fp_library::{
874		/// 	brands::*,
875		/// 	functions::*,
876		/// 	types::*,
877		/// };
878		///
879		/// assert_eq!(
880		/// 	bind::<PairFirstAppliedBrand<String>, _, _>(Pair("a".to_string(), 5), |x| Pair(
881		/// 		"b".to_string(),
882		/// 		x * 2
883		/// 	)),
884		/// 	Pair("ab".to_string(), 10)
885		/// );
886		/// ```
887		fn bind<'a, A: 'a, B: 'a>(
888			ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
889			func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
890		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
891			ma.bind(func)
892		}
893	}
894
895	#[document_type_parameters("The type of the first value in the pair.")]
896	impl<First: 'static> Foldable for PairFirstAppliedBrand<First> {
897		/// Folds the pair from the right (over second).
898		///
899		/// This method performs a right-associative fold of the pair (over second).
900		#[document_signature]
901		///
902		#[document_type_parameters(
903			"The lifetime of the values.",
904			"The brand of the cloneable function to use.",
905			"The type of the elements in the structure.",
906			"The type of the accumulator."
907		)]
908		///
909		#[document_parameters("The folding function.", "The initial value.", "The pair to fold.")]
910		///
911		#[document_returns("`func(a, initial)`.")]
912		///
913		#[document_examples]
914		///
915		/// ```
916		/// use fp_library::{
917		/// 	brands::*,
918		/// 	functions::*,
919		/// 	types::*,
920		/// };
921		///
922		/// assert_eq!(
923		/// 	fold_right::<RcFnBrand, PairFirstAppliedBrand<()>, _, _>(|x, acc| x + acc, 0, Pair((), 5)),
924		/// 	5
925		/// );
926		/// ```
927		fn fold_right<'a, FnBrand, A: 'a + Clone, B: 'a>(
928			func: impl Fn(A, B) -> B + 'a,
929			initial: B,
930			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
931		) -> B
932		where
933			FnBrand: CloneableFn + 'a, {
934			func(fa.1, initial)
935		}
936
937		/// Folds the pair from the left (over second).
938		///
939		/// This method performs a left-associative fold of the pair (over second).
940		#[document_signature]
941		///
942		#[document_type_parameters(
943			"The lifetime of the values.",
944			"The brand of the cloneable function to use.",
945			"The type of the elements in the structure.",
946			"The type of the accumulator."
947		)]
948		///
949		#[document_parameters(
950			"The function to apply to the accumulator and each element.",
951			"The initial value of the accumulator.",
952			"The identity to fold."
953		)]
954		///
955		#[document_returns("`func(initial, a)`.")]
956		#[document_examples]
957		///
958		/// ```
959		/// use fp_library::{
960		/// 	brands::*,
961		/// 	functions::*,
962		/// 	types::*,
963		/// };
964		///
965		/// assert_eq!(
966		/// 	fold_left::<RcFnBrand, PairFirstAppliedBrand<()>, _, _>(|acc, x| acc + x, 0, Pair((), 5)),
967		/// 	5
968		/// );
969		/// ```
970		fn fold_left<'a, FnBrand, A: 'a + Clone, B: 'a>(
971			func: impl Fn(B, A) -> B + 'a,
972			initial: B,
973			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
974		) -> B
975		where
976			FnBrand: CloneableFn + 'a, {
977			func(initial, fa.1)
978		}
979
980		/// Maps the value to a monoid and returns it (over second).
981		///
982		/// This method maps the element of the pair to a monoid and then returns it (over second).
983		#[document_signature]
984		///
985		#[document_type_parameters(
986			"The lifetime of the values.",
987			"The brand of the cloneable function to use.",
988			"The type of the elements in the structure.",
989			"The type of the monoid."
990		)]
991		///
992		#[document_parameters("The mapping function.", "The pair to fold.")]
993		///
994		#[document_returns("`func(a)`.")]
995		///
996		#[document_examples]
997		///
998		/// ```
999		/// use fp_library::{
1000		/// 	brands::*,
1001		/// 	functions::*,
1002		/// 	types::*,
1003		/// };
1004		///
1005		/// assert_eq!(
1006		/// 	fold_map::<RcFnBrand, PairFirstAppliedBrand<()>, _, _>(|x: i32| x.to_string(), Pair((), 5)),
1007		/// 	"5".to_string()
1008		/// );
1009		/// ```
1010		fn fold_map<'a, FnBrand, A: 'a + Clone, M>(
1011			func: impl Fn(A) -> M + 'a,
1012			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1013		) -> M
1014		where
1015			M: Monoid + 'a,
1016			FnBrand: CloneableFn + 'a, {
1017			func(fa.1)
1018		}
1019	}
1020
1021	#[document_type_parameters("The type of the first value in the pair.")]
1022	impl<First: Clone + 'static> Traversable for PairFirstAppliedBrand<First> {
1023		/// Traverses the pair with an applicative function (over second).
1024		///
1025		/// This method maps the element of the pair to a computation, evaluates it, and combines the result into an applicative context (over second).
1026		#[document_signature]
1027		///
1028		#[document_type_parameters(
1029			"The lifetime of the values.",
1030			"The type of the elements in the traversable structure.",
1031			"The type of the elements in the resulting traversable structure.",
1032			"The applicative context."
1033		)]
1034		///
1035		#[document_parameters(
1036			"The function to apply to each element, returning a value in an applicative context.",
1037			"The pair to traverse."
1038		)]
1039		///
1040		#[document_returns("The pair wrapped in the applicative context.")]
1041		#[document_examples]
1042		///
1043		/// ```
1044		/// use fp_library::{
1045		/// 	brands::*,
1046		/// 	functions::*,
1047		/// 	types::*,
1048		/// };
1049		///
1050		/// assert_eq!(
1051		/// 	traverse::<PairFirstAppliedBrand<()>, _, _, OptionBrand>(|x| Some(x * 2), Pair((), 5)),
1052		/// 	Some(Pair((), 10))
1053		/// );
1054		/// ```
1055		fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
1056			func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1057			ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1058		) -> 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>)>)
1059		where
1060			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
1061			let Pair(first, second) = ta;
1062			F::map(move |b| Pair(first.clone(), b), func(second))
1063		}
1064
1065		/// Sequences a pair of applicative (over second).
1066		///
1067		/// This method evaluates the computation inside the pair and accumulates the result into an applicative context (over second).
1068		#[document_signature]
1069		///
1070		#[document_type_parameters(
1071			"The lifetime of the values.",
1072			"The type of the elements in the traversable structure.",
1073			"The applicative context."
1074		)]
1075		///
1076		#[document_parameters("The pair containing the applicative value.")]
1077		///
1078		#[document_returns("The pair wrapped in the applicative context.")]
1079		///
1080		#[document_examples]
1081		///
1082		/// ```
1083		/// use fp_library::{
1084		/// 	brands::*,
1085		/// 	functions::*,
1086		/// 	types::*,
1087		/// };
1088		///
1089		/// assert_eq!(
1090		/// 	sequence::<PairFirstAppliedBrand<()>, _, OptionBrand>(Pair((), Some(5))),
1091		/// 	Some(Pair((), 5))
1092		/// );
1093		/// ```
1094		fn sequence<'a, A: 'a + Clone, F: Applicative>(
1095			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>)>)
1096		) -> 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>)>)
1097		where
1098			Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
1099			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
1100			let Pair(first, second) = ta;
1101			F::map(move |a| Pair(first.clone(), a), second)
1102		}
1103	}
1104
1105	#[document_type_parameters("The type of the first value in the pair.")]
1106	impl<First: 'static> ParFoldable for PairFirstAppliedBrand<First> {
1107		/// Maps the value to a monoid and returns it in parallel (over second).
1108		///
1109		/// This method maps the element of the pair to a monoid and then returns it (over second). The mapping operation may be executed in parallel.
1110		#[document_signature]
1111		///
1112		#[document_type_parameters(
1113			"The lifetime of the values.",
1114			"The brand of the cloneable function wrapper.",
1115			"The element type.",
1116			"The monoid type."
1117		)]
1118		///
1119		#[document_parameters(
1120			"The thread-safe function to map each element to a monoid.",
1121			"The pair to fold."
1122		)]
1123		///
1124		#[document_returns("The combined monoid value.")]
1125		#[document_examples]
1126		///
1127		/// ```
1128		/// use fp_library::{
1129		/// 	brands::*,
1130		/// 	functions::*,
1131		/// 	types::*,
1132		/// };
1133		///
1134		/// let x = Pair("a".to_string(), 1);
1135		/// let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1136		/// assert_eq!(
1137		/// 	par_fold_map::<ArcFnBrand, PairFirstAppliedBrand<String>, _, _>(f, x),
1138		/// 	"1".to_string()
1139		/// );
1140		/// ```
1141		fn par_fold_map<'a, FnBrand, A, M>(
1142			func: <FnBrand as SendCloneableFn>::SendOf<'a, A, M>,
1143			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1144		) -> M
1145		where
1146			FnBrand: 'a + SendCloneableFn,
1147			A: 'a + Clone + Send + Sync,
1148			M: Monoid + Send + Sync + 'a, {
1149			func(fa.1)
1150		}
1151
1152		/// Folds the pair from the right in parallel (over second).
1153		///
1154		/// This method folds the pair by applying a function from right to left, potentially in parallel (over second).
1155		#[document_signature]
1156		///
1157		#[document_type_parameters(
1158			"The lifetime of the values.",
1159			"The brand of the cloneable function wrapper.",
1160			"The element type.",
1161			"The accumulator type."
1162		)]
1163		///
1164		#[document_parameters(
1165			"The thread-safe function to apply to each element and the accumulator.",
1166			"The initial value.",
1167			"The pair to fold."
1168		)]
1169		///
1170		#[document_returns("The final accumulator value.")]
1171		#[document_examples]
1172		///
1173		/// ```
1174		/// use fp_library::{
1175		/// 	brands::*,
1176		/// 	functions::*,
1177		/// 	types::*,
1178		/// };
1179		///
1180		/// let x = Pair("a".to_string(), 1);
1181		/// let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
1182		/// assert_eq!(par_fold_right::<ArcFnBrand, PairFirstAppliedBrand<String>, _, _>(f, 10, x), 11);
1183		/// ```
1184		fn par_fold_right<'a, FnBrand, A, B>(
1185			func: <FnBrand as SendCloneableFn>::SendOf<'a, (A, B), B>,
1186			initial: B,
1187			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1188		) -> B
1189		where
1190			FnBrand: 'a + SendCloneableFn,
1191			A: 'a + Clone + Send + Sync,
1192			B: Send + Sync + 'a, {
1193			func((fa.1, initial))
1194		}
1195	}
1196	// PairSecondAppliedBrand<Second> (Functor over First)
1197
1198	impl_kind! {
1199		#[document_type_parameters("The type of the second value in the pair.")]
1200		impl<Second: 'static> for PairSecondAppliedBrand<Second> {
1201			type Of<'a, A: 'a>: 'a = Pair<A, Second>;
1202		}
1203	}
1204
1205	#[document_type_parameters("The type of the second value in the pair.")]
1206	impl<Second: 'static> Functor for PairSecondAppliedBrand<Second> {
1207		/// Maps a function over the first value in the pair.
1208		///
1209		/// This method applies a function to the first value inside the pair, producing a new pair with the transformed first value. The second value remains unchanged.
1210		#[document_signature]
1211		///
1212		#[document_type_parameters(
1213			"The lifetime of the values.",
1214			"The type of the first value.",
1215			"The type of the result of applying the function."
1216		)]
1217		///
1218		#[document_parameters("The function to apply to the first value.", "The pair to map over.")]
1219		///
1220		#[document_returns(
1221			"A new pair containing the result of applying the function to the first value."
1222		)]
1223		///
1224		#[document_examples]
1225		///
1226		/// ```
1227		/// use fp_library::{
1228		/// 	brands::*,
1229		/// 	functions::*,
1230		/// 	types::*,
1231		/// };
1232		///
1233		/// assert_eq!(map::<PairSecondAppliedBrand<_>, _, _>(|x: i32| x * 2, Pair(5, 1)), Pair(10, 1));
1234		/// ```
1235		fn map<'a, A: 'a, B: 'a>(
1236			func: impl Fn(A) -> B + 'a,
1237			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1238		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1239			fa.map_first(func)
1240		}
1241	}
1242
1243	#[document_type_parameters("The type of the second value in the pair.")]
1244	impl<Second: Clone + 'static> Lift for PairSecondAppliedBrand<Second>
1245	where
1246		Second: Semigroup,
1247	{
1248		/// Lifts a binary function into the pair context (over first).
1249		///
1250		/// This method lifts a binary function to operate on the first values within the pair context. The second values are combined using their `Semigroup` implementation.
1251		#[document_signature]
1252		///
1253		#[document_type_parameters(
1254			"The lifetime of the values.",
1255			"The type of the first first value.",
1256			"The type of the second first value.",
1257			"The type of the result first value."
1258		)]
1259		///
1260		#[document_parameters(
1261			"The binary function to apply to the first values.",
1262			"The first pair.",
1263			"The second pair."
1264		)]
1265		///
1266		#[document_returns(
1267			"A new pair where the first values are combined using `f` and the second values are combined using `Semigroup::append`."
1268		)]
1269		#[document_examples]
1270		///
1271		/// ```
1272		/// use fp_library::{
1273		/// 	brands::*,
1274		/// 	functions::*,
1275		/// 	types::*,
1276		/// };
1277		///
1278		/// assert_eq!(
1279		/// 	lift2::<PairSecondAppliedBrand<String>, _, _, _>(
1280		/// 		|x, y| x + y,
1281		/// 		Pair(1, "a".to_string()),
1282		/// 		Pair(2, "b".to_string())
1283		/// 	),
1284		/// 	Pair(3, "ab".to_string())
1285		/// );
1286		/// ```
1287		fn lift2<'a, A, B, C>(
1288			func: impl Fn(A, B) -> C + 'a,
1289			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1290			fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
1291		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
1292		where
1293			A: Clone + 'a,
1294			B: Clone + 'a,
1295			C: 'a, {
1296			Pair(func(fa.0, fb.0), Semigroup::append(fa.1, fb.1))
1297		}
1298	}
1299
1300	#[document_type_parameters("The type of the second value in the pair.")]
1301	impl<Second: Clone + 'static> Pointed for PairSecondAppliedBrand<Second>
1302	where
1303		Second: Monoid,
1304	{
1305		/// Wraps a value in a pair (with empty second).
1306		///
1307		/// This method wraps a value in a pair, using the `Monoid::empty()` value for the second element.
1308		#[document_signature]
1309		///
1310		#[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
1311		///
1312		#[document_parameters("The value to wrap.")]
1313		///
1314		#[document_returns("A pair containing `a` and the empty value of the second type.")]
1315		///
1316		#[document_examples]
1317		///
1318		/// ```
1319		/// use fp_library::{
1320		/// 	brands::*,
1321		/// 	functions::*,
1322		/// 	types::*,
1323		/// };
1324		///
1325		/// assert_eq!(pure::<PairSecondAppliedBrand<String>, _>(5), Pair(5, "".to_string()));
1326		/// ```
1327		fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
1328			Pair(a, Monoid::empty())
1329		}
1330	}
1331
1332	#[document_type_parameters("The type of the second value in the pair.")]
1333	impl<Second: Clone + Semigroup + 'static> ApplyFirst for PairSecondAppliedBrand<Second> {}
1334
1335	#[document_type_parameters("The type of the second value in the pair.")]
1336	impl<Second: Clone + Semigroup + 'static> ApplySecond for PairSecondAppliedBrand<Second> {}
1337
1338	#[document_type_parameters("The type of the second value in the pair.")]
1339	impl<Second: Clone + 'static> Semiapplicative for PairSecondAppliedBrand<Second>
1340	where
1341		Second: Semigroup,
1342	{
1343		/// Applies a wrapped function to a wrapped value (over first).
1344		///
1345		/// This method applies a function wrapped in a result (as error) to a value wrapped in a result (as error).
1346		#[document_signature]
1347		///
1348		#[document_type_parameters(
1349			"The lifetime of the values.",
1350			"The brand of the cloneable function wrapper.",
1351			"The type of the input value.",
1352			"The type of the output value."
1353		)]
1354		///
1355		#[document_parameters(
1356			"The pair containing the function (in Err).",
1357			"The pair containing the value (in Err)."
1358		)]
1359		///
1360		#[document_returns(
1361			"`Err(f(a))` if both are `Err`, otherwise the first success encountered."
1362		)]
1363		#[document_examples]
1364		///
1365		/// ```
1366		/// use fp_library::{
1367		/// 	brands::*,
1368		/// 	functions::*,
1369		/// 	types::*,
1370		/// };
1371		///
1372		/// let f = Pair(cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2), "a".to_string());
1373		/// assert_eq!(
1374		/// 	apply::<RcFnBrand, PairSecondAppliedBrand<String>, _, _>(f, Pair(5, "b".to_string())),
1375		/// 	Pair(10, "ab".to_string())
1376		/// );
1377		/// ```
1378		fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
1379			ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
1380			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1381		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1382			Pair(ff.0(fa.0), Semigroup::append(ff.1, fa.1))
1383		}
1384	}
1385
1386	#[document_type_parameters("The type of the second value in the pair.")]
1387	impl<Second: Clone + 'static> Semimonad for PairSecondAppliedBrand<Second>
1388	where
1389		Second: Semigroup,
1390	{
1391		/// Chains pair computations (over first).
1392		///
1393		/// This method chains two computations, where the second computation depends on the result of the first (over error).
1394		#[document_signature]
1395		///
1396		#[document_type_parameters(
1397			"The lifetime of the values.",
1398			"The type of the result of the first computation.",
1399			"The type of the result of the second computation."
1400		)]
1401		///
1402		#[document_parameters("The first result.", "The function to apply to the error value.")]
1403		///
1404		#[document_returns(
1405			"The result of applying `f` to the error if `ma` is `Err`, otherwise the original success."
1406		)]
1407		///
1408		#[document_examples]
1409		///
1410		/// ```
1411		/// use fp_library::{
1412		/// 	brands::*,
1413		/// 	functions::*,
1414		/// 	types::*,
1415		/// };
1416		///
1417		/// assert_eq!(
1418		/// 	bind::<PairSecondAppliedBrand<String>, _, _>(Pair(5, "a".to_string()), |x| Pair(
1419		/// 		x * 2,
1420		/// 		"b".to_string()
1421		/// 	)),
1422		/// 	Pair(10, "ab".to_string())
1423		/// );
1424		/// ```
1425		fn bind<'a, A: 'a, B: 'a>(
1426			ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1427			func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1428		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1429			ma.bind_first(func)
1430		}
1431	}
1432
1433	#[document_type_parameters("The type of the second value in the pair.")]
1434	impl<Second: 'static> Foldable for PairSecondAppliedBrand<Second> {
1435		/// Folds the pair from the right (over first).
1436		///
1437		/// This method performs a right-associative fold of the result (over error).
1438		#[document_signature]
1439		///
1440		#[document_type_parameters(
1441			"The lifetime of the values.",
1442			"The brand of the cloneable function to use.",
1443			"The type of the elements in the structure.",
1444			"The type of the accumulator."
1445		)]
1446		///
1447		#[document_parameters("The folding function.", "The initial value.", "The result to fold.")]
1448		///
1449		#[document_returns("`func(a, initial)` if `fa` is `Err(a)`, otherwise `initial`.")]
1450		///
1451		#[document_examples]
1452		///
1453		/// ```
1454		/// use fp_library::{
1455		/// 	brands::*,
1456		/// 	functions::*,
1457		/// 	types::*,
1458		/// };
1459		///
1460		/// assert_eq!(
1461		/// 	fold_right::<RcFnBrand, PairSecondAppliedBrand<()>, _, _>(|x, acc| x + acc, 0, Pair(5, ())),
1462		/// 	5
1463		/// );
1464		/// ```
1465		fn fold_right<'a, FnBrand, A: 'a + Clone, B: 'a>(
1466			func: impl Fn(A, B) -> B + 'a,
1467			initial: B,
1468			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1469		) -> B
1470		where
1471			FnBrand: CloneableFn + 'a, {
1472			func(fa.0, initial)
1473		}
1474
1475		/// Folds the pair from the left (over first).
1476		///
1477		/// This method performs a left-associative fold of the result (over error).
1478		#[document_signature]
1479		///
1480		#[document_type_parameters(
1481			"The lifetime of the values.",
1482			"The brand of the cloneable function to use.",
1483			"The type of the elements in the structure.",
1484			"The type of the accumulator."
1485		)]
1486		///
1487		#[document_parameters("The folding function.", "The initial value.", "The result to fold.")]
1488		///
1489		#[document_returns("`func(initial, a)` if `fa` is `Err(a)`, otherwise `initial`.")]
1490		///
1491		#[document_examples]
1492		///
1493		/// ```
1494		/// use fp_library::{
1495		/// 	brands::*,
1496		/// 	functions::*,
1497		/// 	types::*,
1498		/// };
1499		///
1500		/// assert_eq!(
1501		/// 	fold_left::<RcFnBrand, PairSecondAppliedBrand<()>, _, _>(|acc, x| acc + x, 0, Pair(5, ())),
1502		/// 	5
1503		/// );
1504		/// ```
1505		fn fold_left<'a, FnBrand, A: 'a + Clone, B: 'a>(
1506			func: impl Fn(B, A) -> B + 'a,
1507			initial: B,
1508			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1509		) -> B
1510		where
1511			FnBrand: CloneableFn + 'a, {
1512			func(initial, fa.0)
1513		}
1514
1515		/// Maps the value to a monoid and returns it (over first).
1516		///
1517		/// This method maps the element of the result to a monoid and then returns it (over error).
1518		#[document_signature]
1519		///
1520		#[document_type_parameters(
1521			"The lifetime of the values.",
1522			"The brand of the cloneable function to use.",
1523			"The type of the elements in the structure.",
1524			"The type of the monoid."
1525		)]
1526		///
1527		#[document_parameters("The mapping function.", "The result to fold.")]
1528		///
1529		#[document_returns("`func(a)` if `fa` is `Err(a)`, otherwise `M::empty()`.")]
1530		///
1531		#[document_examples]
1532		///
1533		/// ```
1534		/// use fp_library::{
1535		/// 	brands::*,
1536		/// 	functions::*,
1537		/// 	types::*,
1538		/// };
1539		///
1540		/// assert_eq!(
1541		/// 	fold_map::<RcFnBrand, PairSecondAppliedBrand<()>, _, _>(
1542		/// 		|x: i32| x.to_string(),
1543		/// 		Pair(5, ())
1544		/// 	),
1545		/// 	"5".to_string()
1546		/// );
1547		/// ```
1548		fn fold_map<'a, FnBrand, A: 'a + Clone, M>(
1549			func: impl Fn(A) -> M + 'a,
1550			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1551		) -> M
1552		where
1553			M: Monoid + 'a,
1554			FnBrand: CloneableFn + 'a, {
1555			func(fa.0)
1556		}
1557	}
1558
1559	#[document_type_parameters("The type of the second value in the pair.")]
1560	impl<Second: Clone + 'static> Traversable for PairSecondAppliedBrand<Second> {
1561		/// Traverses the pair with an applicative function (over first).
1562		///
1563		/// This method maps the element of the result to a computation, evaluates it, and combines the result into an applicative context (over error).
1564		#[document_signature]
1565		///
1566		#[document_type_parameters(
1567			"The lifetime of the values.",
1568			"The type of the elements in the traversable structure.",
1569			"The type of the elements in the resulting traversable structure.",
1570			"The applicative context."
1571		)]
1572		///
1573		#[document_parameters("The function to apply.", "The result to traverse.")]
1574		///
1575		#[document_returns("The result wrapped in the applicative context.")]
1576		///
1577		#[document_examples]
1578		///
1579		/// ```
1580		/// use fp_library::{
1581		/// 	brands::*,
1582		/// 	functions::*,
1583		/// 	types::*,
1584		/// };
1585		///
1586		/// assert_eq!(
1587		/// 	traverse::<PairSecondAppliedBrand<()>, _, _, OptionBrand>(|x| Some(x * 2), Pair(5, ())),
1588		/// 	Some(Pair(10, ()))
1589		/// );
1590		/// ```
1591		fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
1592			func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1593			ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1594		) -> 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>)>)
1595		where
1596			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
1597			let Pair(first, second) = ta;
1598			F::map(move |b| Pair(b, second.clone()), func(first))
1599		}
1600
1601		/// Sequences a pair of applicative (over first).
1602		///
1603		/// This method evaluates the computation inside the result and accumulates the result into an applicative context (over error).
1604		#[document_signature]
1605		///
1606		#[document_type_parameters(
1607			"The lifetime of the values.",
1608			"The type of the elements in the traversable structure.",
1609			"The applicative context."
1610		)]
1611		///
1612		#[document_parameters("The result containing the applicative value.")]
1613		///
1614		#[document_returns("The result wrapped in the applicative context.")]
1615		///
1616		#[document_examples]
1617		///
1618		/// ```
1619		/// use fp_library::{
1620		/// 	brands::*,
1621		/// 	functions::*,
1622		/// 	types::*,
1623		/// };
1624		///
1625		/// assert_eq!(
1626		/// 	sequence::<PairSecondAppliedBrand<()>, _, OptionBrand>(Pair(Some(5), ())),
1627		/// 	Some(Pair(5, ()))
1628		/// );
1629		/// ```
1630		fn sequence<'a, A: 'a + Clone, F: Applicative>(
1631			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>)>)
1632		) -> 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>)>)
1633		where
1634			Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
1635			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
1636			let Pair(first, second) = ta;
1637			F::map(move |a| Pair(a, second.clone()), first)
1638		}
1639	}
1640
1641	#[document_type_parameters("The type of the second value in the pair.")]
1642	impl<Second: 'static> ParFoldable for PairSecondAppliedBrand<Second> {
1643		/// Maps the value to a monoid and returns it in parallel (over first).
1644		///
1645		/// This method maps the element of the pair to a monoid and then returns it (over first). The mapping operation may be executed in parallel.
1646		#[document_signature]
1647		///
1648		#[document_type_parameters(
1649			"The lifetime of the values.",
1650			"The brand of the cloneable function wrapper.",
1651			"The element type.",
1652			"The monoid type."
1653		)]
1654		///
1655		#[document_parameters(
1656			"The thread-safe function to map each element to a monoid.",
1657			"The pair to fold."
1658		)]
1659		///
1660		#[document_returns("The combined monoid value.")]
1661		#[document_examples]
1662		///
1663		/// ```
1664		/// use fp_library::{
1665		/// 	brands::*,
1666		/// 	functions::*,
1667		/// 	types::*,
1668		/// };
1669		///
1670		/// let x = Pair(1, "a".to_string());
1671		/// let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1672		/// assert_eq!(
1673		/// 	par_fold_map::<ArcFnBrand, PairSecondAppliedBrand<String>, _, _>(f, x),
1674		/// 	"1".to_string()
1675		/// );
1676		/// ```
1677		fn par_fold_map<'a, FnBrand, A, M>(
1678			func: <FnBrand as SendCloneableFn>::SendOf<'a, A, M>,
1679			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1680		) -> M
1681		where
1682			FnBrand: 'a + SendCloneableFn,
1683			A: 'a + Clone + Send + Sync,
1684			M: Monoid + Send + Sync + 'a, {
1685			func(fa.0)
1686		}
1687
1688		/// Folds the pair from the right in parallel (over first).
1689		///
1690		/// This method folds the pair by applying a function from right to left, potentially in parallel (over first).
1691		#[document_signature]
1692		///
1693		#[document_type_parameters(
1694			"The lifetime of the values.",
1695			"The brand of the cloneable function wrapper.",
1696			"The element type.",
1697			"The accumulator type."
1698		)]
1699		///
1700		#[document_parameters(
1701			"The thread-safe function to apply to each element and the accumulator.",
1702			"The initial value.",
1703			"The pair to fold."
1704		)]
1705		///
1706		#[document_returns("The final accumulator value.")]
1707		#[document_examples]
1708		///
1709		/// ```
1710		/// use fp_library::{
1711		/// 	brands::*,
1712		/// 	functions::*,
1713		/// 	types::*,
1714		/// };
1715		///
1716		/// let x = Pair(1, "a".to_string());
1717		/// let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
1718		/// assert_eq!(par_fold_right::<ArcFnBrand, PairSecondAppliedBrand<String>, _, _>(f, 10, x), 11);
1719		/// ```
1720		fn par_fold_right<'a, FnBrand, A, B>(
1721			func: <FnBrand as SendCloneableFn>::SendOf<'a, (A, B), B>,
1722			initial: B,
1723			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1724		) -> B
1725		where
1726			FnBrand: 'a + SendCloneableFn,
1727			A: 'a + Clone + Send + Sync,
1728			B: Send + Sync + 'a, {
1729			func((fa.0, initial))
1730		}
1731	}
1732}
1733pub use inner::*;
1734
1735#[cfg(test)]
1736mod tests {
1737	use {
1738		super::inner::*,
1739		crate::{
1740			brands::*,
1741			classes::{
1742				CloneableFn,
1743				bifunctor::*,
1744			},
1745			functions::*,
1746		},
1747		quickcheck_macros::quickcheck,
1748	};
1749
1750	// Bifunctor Tests
1751
1752	/// Tests `bimap` on `Pair`.
1753	#[test]
1754	fn test_bimap() {
1755		let x = Pair(1, 5);
1756		assert_eq!(bimap::<PairBrand, _, _, _, _>(|a| a + 1, |b| b * 2, x), Pair(2, 10));
1757	}
1758
1759	// Bifunctor Laws
1760
1761	/// Tests the identity law for Bifunctor.
1762	#[quickcheck]
1763	fn bifunctor_identity(
1764		first: String,
1765		second: i32,
1766	) -> bool {
1767		let x = Pair(first, second);
1768		bimap::<PairBrand, _, _, _, _>(identity, identity, x.clone()) == x
1769	}
1770
1771	/// Tests the composition law for Bifunctor.
1772	#[quickcheck]
1773	fn bifunctor_composition(
1774		first: i32,
1775		second: i32,
1776	) -> bool {
1777		let x = Pair(first, second);
1778		let f = |x: i32| x.wrapping_add(1);
1779		let g = |x: i32| x.wrapping_mul(2);
1780		let h = |x: i32| x.wrapping_sub(1);
1781		let i = |x: i32| if x == 0 { 0 } else { x.wrapping_div(2) };
1782
1783		bimap::<PairBrand, _, _, _, _>(compose(f, g), compose(h, i), x)
1784			== bimap::<PairBrand, _, _, _, _>(f, h, bimap::<PairBrand, _, _, _, _>(g, i, x))
1785	}
1786
1787	// Functor Laws
1788
1789	/// Tests the identity law for Functor.
1790	#[quickcheck]
1791	fn functor_identity(
1792		first: String,
1793		second: i32,
1794	) -> bool {
1795		let x = Pair(first, second);
1796		map::<PairFirstAppliedBrand<String>, _, _>(identity, x.clone()) == x
1797	}
1798
1799	/// Tests the composition law for Functor.
1800	#[quickcheck]
1801	fn functor_composition(
1802		first: String,
1803		second: i32,
1804	) -> bool {
1805		let x = Pair(first, second);
1806		let f = |x: i32| x.wrapping_add(1);
1807		let g = |x: i32| x.wrapping_mul(2);
1808		map::<PairFirstAppliedBrand<String>, _, _>(compose(f, g), x.clone())
1809			== map::<PairFirstAppliedBrand<String>, _, _>(
1810				f,
1811				map::<PairFirstAppliedBrand<String>, _, _>(g, x),
1812			)
1813	}
1814
1815	// Applicative Laws
1816
1817	/// Tests the identity law for Applicative.
1818	#[quickcheck]
1819	fn applicative_identity(
1820		first: String,
1821		second: i32,
1822	) -> bool {
1823		let v = Pair(first, second);
1824		apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(
1825			pure::<PairFirstAppliedBrand<String>, _>(<RcFnBrand as CloneableFn>::new(identity)),
1826			v.clone(),
1827		) == v
1828	}
1829
1830	/// Tests the homomorphism law for Applicative.
1831	#[quickcheck]
1832	fn applicative_homomorphism(x: i32) -> bool {
1833		let f = |x: i32| x.wrapping_mul(2);
1834		apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(
1835			pure::<PairFirstAppliedBrand<String>, _>(<RcFnBrand as CloneableFn>::new(f)),
1836			pure::<PairFirstAppliedBrand<String>, _>(x),
1837		) == pure::<PairFirstAppliedBrand<String>, _>(f(x))
1838	}
1839
1840	/// Tests the composition law for Applicative.
1841	#[quickcheck]
1842	fn applicative_composition(
1843		w_first: String,
1844		w_second: i32,
1845		u_seed: i32,
1846		v_seed: i32,
1847	) -> bool {
1848		let w = Pair(w_first, w_second);
1849
1850		let u_fn = <RcFnBrand as CloneableFn>::new(move |x: i32| x.wrapping_add(u_seed));
1851		let u = pure::<PairFirstAppliedBrand<String>, _>(u_fn);
1852
1853		let v_fn = <RcFnBrand as CloneableFn>::new(move |x: i32| x.wrapping_mul(v_seed));
1854		let v = pure::<PairFirstAppliedBrand<String>, _>(v_fn);
1855
1856		// RHS: u <*> (v <*> w)
1857		let vw = apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(v.clone(), w.clone());
1858		let rhs = apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(u.clone(), vw);
1859
1860		// LHS: pure(compose) <*> u <*> v <*> w
1861		let compose_fn = <RcFnBrand as CloneableFn>::new(|f: std::rc::Rc<dyn Fn(i32) -> i32>| {
1862			let f = f.clone();
1863			<RcFnBrand as CloneableFn>::new(move |g: std::rc::Rc<dyn Fn(i32) -> i32>| {
1864				let f = f.clone();
1865				let g = g.clone();
1866				<RcFnBrand as CloneableFn>::new(move |x| f(g(x)))
1867			})
1868		});
1869
1870		let pure_compose = pure::<PairFirstAppliedBrand<String>, _>(compose_fn);
1871		let u_applied = apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(pure_compose, u);
1872		let uv = apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(u_applied, v);
1873		let lhs = apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(uv, w);
1874
1875		lhs == rhs
1876	}
1877
1878	/// Tests the interchange law for Applicative.
1879	#[quickcheck]
1880	fn applicative_interchange(
1881		y: i32,
1882		u_seed: i32,
1883	) -> bool {
1884		// u <*> pure y = pure ($ y) <*> u
1885		let f = move |x: i32| x.wrapping_mul(u_seed);
1886		let u = pure::<PairFirstAppliedBrand<String>, _>(<RcFnBrand as CloneableFn>::new(f));
1887
1888		let lhs = apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(
1889			u.clone(),
1890			pure::<PairFirstAppliedBrand<String>, _>(y),
1891		);
1892
1893		let rhs_fn =
1894			<RcFnBrand as CloneableFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
1895		let rhs = apply::<RcFnBrand, PairFirstAppliedBrand<String>, _, _>(
1896			pure::<PairFirstAppliedBrand<String>, _>(rhs_fn),
1897			u,
1898		);
1899
1900		lhs == rhs
1901	}
1902
1903	// Monad Laws
1904
1905	/// Tests the left identity law for Monad.
1906	#[quickcheck]
1907	fn monad_left_identity(a: i32) -> bool {
1908		let f = |x: i32| Pair("f".to_string(), x.wrapping_mul(2));
1909		bind::<PairFirstAppliedBrand<String>, _, _>(pure::<PairFirstAppliedBrand<String>, _>(a), f)
1910			== f(a)
1911	}
1912
1913	/// Tests the right identity law for Monad.
1914	#[quickcheck]
1915	fn monad_right_identity(
1916		first: String,
1917		second: i32,
1918	) -> bool {
1919		let m = Pair(first, second);
1920		bind::<PairFirstAppliedBrand<String>, _, _>(
1921			m.clone(),
1922			pure::<PairFirstAppliedBrand<String>, _>,
1923		) == m
1924	}
1925
1926	/// Tests the associativity law for Monad.
1927	#[quickcheck]
1928	fn monad_associativity(
1929		first: String,
1930		second: i32,
1931	) -> bool {
1932		let m = Pair(first, second);
1933		let f = |x: i32| Pair("f".to_string(), x.wrapping_mul(2));
1934		let g = |x: i32| Pair("g".to_string(), x.wrapping_add(1));
1935		bind::<PairFirstAppliedBrand<String>, _, _>(
1936			bind::<PairFirstAppliedBrand<String>, _, _>(m.clone(), f),
1937			g,
1938		) == bind::<PairFirstAppliedBrand<String>, _, _>(m, |x| {
1939			bind::<PairFirstAppliedBrand<String>, _, _>(f(x), g)
1940		})
1941	}
1942
1943	// ParFoldable Tests for PairFirstAppliedBrand (Functor over Second)
1944
1945	/// Tests `par_fold_map` on `PairFirstAppliedBrand`.
1946	#[test]
1947	fn par_fold_map_pair_with_first() {
1948		let x = Pair("a".to_string(), 1);
1949		let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1950		assert_eq!(
1951			par_fold_map::<ArcFnBrand, PairFirstAppliedBrand<String>, _, _>(f, x),
1952			"1".to_string()
1953		);
1954	}
1955
1956	/// Tests `par_fold_right` on `PairFirstAppliedBrand`.
1957	#[test]
1958	fn par_fold_right_pair_with_first() {
1959		let x = Pair("a".to_string(), 1);
1960		let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
1961		assert_eq!(par_fold_right::<ArcFnBrand, PairFirstAppliedBrand<String>, _, _>(f, 10, x), 11);
1962	}
1963
1964	// ParFoldable Tests for PairSecondAppliedBrand (Functor over First)
1965
1966	/// Tests `par_fold_map` on `PairSecondAppliedBrand`.
1967	#[test]
1968	fn par_fold_map_pair_with_second() {
1969		let x = Pair(1, "a".to_string());
1970		let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1971		assert_eq!(
1972			par_fold_map::<ArcFnBrand, PairSecondAppliedBrand<String>, _, _>(f, x),
1973			"1".to_string()
1974		);
1975	}
1976
1977	/// Tests `par_fold_right` on `PairSecondAppliedBrand`.
1978	#[test]
1979	fn par_fold_right_pair_with_second() {
1980		let x = Pair(1, "a".to_string());
1981		let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
1982		assert_eq!(
1983			par_fold_right::<ArcFnBrand, PairSecondAppliedBrand<String>, _, _>(f, 10, x),
1984			11
1985		);
1986	}
1987}