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