Skip to main content

fp_library/types/
tuple_2.rs

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