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