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 [`Tuple2Brand`](crate::brands::Tuple2Brand), 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		#[multi_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		/// 	classes::semiapplicative::apply as explicit_apply,
616		/// 	functions::*,
617		/// };
618		///
619		/// let f = ("a".to_string(), lift_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2));
620		/// assert_eq!(
621		/// 	explicit_apply::<RcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(f, ("b".to_string(), 5)),
622		/// 	("ab".to_string(), 10)
623		/// );
624		/// ```
625		fn apply<'a, FnBrand: 'a + CloneFn, A: 'a + Clone, B: 'a>(
626			ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneFn>::Of<'a, A, B>>),
627			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
628		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
629			(Semigroup::append(ff.0, fa.0), ff.1(fa.1))
630		}
631	}
632
633	#[document_type_parameters("The type of the first value in the tuple.")]
634	impl<First: Clone + 'static> Semimonad for Tuple2FirstAppliedBrand<First>
635	where
636		First: Semigroup,
637	{
638		/// Chains tuple computations (over second).
639		///
640		/// 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.
641		#[document_signature]
642		///
643		#[document_type_parameters(
644			"The lifetime of the values.",
645			"The type of the result of the first computation.",
646			"The type of the result of the second computation."
647		)]
648		///
649		#[document_parameters("The first tuple.", "The function to apply to the second value.")]
650		///
651		#[document_returns("A new tuple where the first values are combined.")]
652		///
653		#[document_examples]
654		///
655		/// ```
656		/// use fp_library::{
657		/// 	brands::*,
658		/// 	functions::*,
659		/// };
660		///
661		/// assert_eq!(
662		/// 	explicit::bind::<Tuple2FirstAppliedBrand<String>, _, _, _, _>(("a".to_string(), 5), |x| (
663		/// 		"b".to_string(),
664		/// 		x * 2
665		/// 	)),
666		/// 	("ab".to_string(), 10)
667		/// );
668		/// ```
669		fn bind<'a, A: 'a, B: 'a>(
670			ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
671			func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
672		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
673			let (first, second) = ma;
674			let (next_first, next_second) = func(second);
675			(Semigroup::append(first, next_first), next_second)
676		}
677	}
678
679	#[document_type_parameters("The type of the first value in the tuple.")]
680	impl<First: Clone + 'static> MonadRec for Tuple2FirstAppliedBrand<First>
681	where
682		First: Monoid,
683	{
684		/// Performs tail-recursive monadic computation over a tuple (varying the second element).
685		///
686		/// Iteratively applies the step function, accumulating the first element
687		/// via `Semigroup::append` at each iteration. When the step function returns
688		/// `ControlFlow::Break`, the accumulated first element and the final result are returned.
689		#[document_signature]
690		///
691		#[document_type_parameters(
692			"The lifetime of the computation.",
693			"The type of the initial value and loop state.",
694			"The type of the result."
695		)]
696		///
697		#[document_parameters("The step function.", "The initial value.")]
698		///
699		#[document_returns(
700			"A tuple with the accumulated first value and the result of the computation."
701		)]
702		///
703		#[document_examples]
704		///
705		/// ```
706		/// use {
707		/// 	core::ops::ControlFlow,
708		/// 	fp_library::{
709		/// 		brands::*,
710		/// 		functions::*,
711		/// 		types::*,
712		/// 	},
713		/// };
714		///
715		/// let result = tail_rec_m::<Tuple2FirstAppliedBrand<String>, _, _>(
716		/// 	|n| {
717		/// 		if n < 3 {
718		/// 			(format!("{n},"), ControlFlow::Continue(n + 1))
719		/// 		} else {
720		/// 			(format!("{n}"), ControlFlow::Break(n))
721		/// 		}
722		/// 	},
723		/// 	0,
724		/// );
725		/// assert_eq!(result, ("0,1,2,3".to_string(), 3));
726		/// ```
727		fn tail_rec_m<'a, A: 'a, B: 'a>(
728			func: impl Fn(
729				A,
730			)
731				-> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, ControlFlow<B, A>>)
732			+ 'a,
733			initial: A,
734		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
735			let mut acc: First = Monoid::empty();
736			let mut current = initial;
737			loop {
738				let (first, step) = func(current);
739				acc = Semigroup::append(acc, first);
740				match step {
741					ControlFlow::Continue(next) => current = next,
742					ControlFlow::Break(b) => return (acc, b),
743				}
744			}
745		}
746	}
747
748	#[document_type_parameters("The type of the first value in the tuple.")]
749	impl<First: 'static> Foldable for Tuple2FirstAppliedBrand<First> {
750		/// Folds the tuple from the right (over second).
751		///
752		/// This method performs a right-associative fold of the tuple (over second).
753		#[document_signature]
754		///
755		#[document_type_parameters(
756			"The lifetime of the values.",
757			"The brand of the cloneable function to use.",
758			"The type of the elements in the structure.",
759			"The type of the accumulator."
760		)]
761		///
762		#[document_parameters("The folding function.", "The initial value.", "The tuple to fold.")]
763		///
764		#[document_returns("`func(a, initial)`.")]
765		///
766		#[document_examples]
767		///
768		/// ```
769		/// use fp_library::{
770		/// 	brands::*,
771		/// 	functions::*,
772		/// };
773		///
774		/// assert_eq!(
775		/// 	explicit::fold_right::<RcFnBrand, Tuple2FirstAppliedBrand<()>, _, _, _, _>(
776		/// 		|x, acc| x + acc,
777		/// 		0,
778		/// 		((), 5)
779		/// 	),
780		/// 	5
781		/// );
782		/// ```
783		fn fold_right<'a, FnBrand, A: 'a + Clone, B: 'a>(
784			func: impl Fn(A, B) -> B + 'a,
785			initial: B,
786			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
787		) -> B
788		where
789			FnBrand: CloneFn + 'a, {
790			func(fa.1, initial)
791		}
792
793		/// Folds the tuple from the left (over second).
794		///
795		/// This method performs a left-associative fold of the tuple (over second).
796		#[document_signature]
797		///
798		#[document_type_parameters(
799			"The lifetime of the values.",
800			"The brand of the cloneable function to use.",
801			"The type of the elements in the structure.",
802			"The type of the accumulator."
803		)]
804		///
805		#[document_parameters(
806			"The function to apply to the accumulator and each element.",
807			"The initial value of the accumulator.",
808			"The tuple to fold."
809		)]
810		///
811		#[document_returns("`func(initial, a)`.")]
812		#[document_examples]
813		///
814		/// ```
815		/// use fp_library::{
816		/// 	brands::*,
817		/// 	functions::*,
818		/// };
819		///
820		/// assert_eq!(
821		/// 	explicit::fold_left::<RcFnBrand, Tuple2FirstAppliedBrand<()>, _, _, _, _>(
822		/// 		|acc, x| acc + x,
823		/// 		0,
824		/// 		((), 5)
825		/// 	),
826		/// 	5
827		/// );
828		/// ```
829		fn fold_left<'a, FnBrand, A: 'a + Clone, B: 'a>(
830			func: impl Fn(B, A) -> B + 'a,
831			initial: B,
832			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
833		) -> B
834		where
835			FnBrand: CloneFn + 'a, {
836			func(initial, fa.1)
837		}
838
839		/// Maps the value to a monoid and returns it (over second).
840		///
841		/// This method maps the element of the tuple to a monoid and then returns it (over second).
842		#[document_signature]
843		///
844		#[document_type_parameters(
845			"The lifetime of the values.",
846			"The brand of the cloneable function to use.",
847			"The type of the elements in the structure.",
848			"The type of the monoid."
849		)]
850		///
851		#[document_parameters("The mapping function.", "The tuple to fold.")]
852		///
853		#[document_returns("`func(a)`.")]
854		///
855		#[document_examples]
856		///
857		/// ```
858		/// use fp_library::{
859		/// 	brands::*,
860		/// 	functions::*,
861		/// };
862		///
863		/// assert_eq!(
864		/// 	explicit::fold_map::<RcFnBrand, Tuple2FirstAppliedBrand<()>, _, _, _, _>(
865		/// 		|x: i32| x.to_string(),
866		/// 		((), 5)
867		/// 	),
868		/// 	"5".to_string()
869		/// );
870		/// ```
871		fn fold_map<'a, FnBrand, A: 'a + Clone, M>(
872			func: impl Fn(A) -> M + 'a,
873			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
874		) -> M
875		where
876			M: Monoid + 'a,
877			FnBrand: CloneFn + 'a, {
878			func(fa.1)
879		}
880	}
881
882	#[document_type_parameters("The type of the first value in the tuple.")]
883	impl<First: Clone + 'static> Traversable for Tuple2FirstAppliedBrand<First> {
884		/// Traverses the tuple with an applicative function (over second).
885		///
886		/// This method maps the element of the tuple to a computation, evaluates it, and combines the result into an applicative context (over second).
887		#[document_signature]
888		///
889		#[document_type_parameters(
890			"The lifetime of the values.",
891			"The type of the elements in the traversable structure.",
892			"The type of the elements in the resulting traversable structure.",
893			"The applicative context."
894		)]
895		///
896		#[document_parameters(
897			"The function to apply to each element, returning a value in an applicative context.",
898			"The tuple to traverse."
899		)]
900		///
901		#[document_returns("The tuple wrapped in the applicative context.")]
902		#[document_examples]
903		///
904		/// ```
905		/// use fp_library::{
906		/// 	brands::*,
907		/// 	functions::*,
908		/// };
909		///
910		/// assert_eq!(
911		/// 	explicit::traverse::<RcFnBrand, Tuple2FirstAppliedBrand<()>, _, _, OptionBrand, _, _>(
912		/// 		|x| Some(x * 2),
913		/// 		((), 5)
914		/// 	),
915		/// 	Some(((), 10))
916		/// );
917		/// ```
918		fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
919			func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
920			ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
921		) -> 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>)>)
922		where
923			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
924			let (first, second) = ta;
925			F::map(move |b| (first.clone(), b), func(second))
926		}
927
928		/// Sequences a tuple of applicative (over second).
929		///
930		/// This method evaluates the computation inside the tuple and accumulates the result into an applicative context (over second).
931		#[document_signature]
932		///
933		#[document_type_parameters(
934			"The lifetime of the values.",
935			"The type of the elements in the traversable structure.",
936			"The applicative context."
937		)]
938		///
939		#[document_parameters("The tuple containing the applicative value.")]
940		///
941		#[document_returns("The tuple wrapped in the applicative context.")]
942		///
943		#[document_examples]
944		///
945		/// ```
946		/// use fp_library::{
947		/// 	brands::*,
948		/// 	functions::*,
949		/// };
950		///
951		/// assert_eq!(
952		/// 	sequence::<Tuple2FirstAppliedBrand<()>, _, OptionBrand>(((), Some(5))),
953		/// 	Some(((), 5))
954		/// );
955		/// ```
956		fn sequence<'a, A: 'a + Clone, F: Applicative>(
957			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>)>)
958		) -> 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>)>)
959		where
960			Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
961			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
962			let (first, second) = ta;
963			F::map(move |a| (first.clone(), a), second)
964		}
965	}
966
967	// -- By-reference trait implementations for Tuple2FirstAppliedBrand --
968
969	#[document_type_parameters("The type of the first value in the tuple.")]
970	impl<First: Clone + 'static> RefFunctor for Tuple2FirstAppliedBrand<First> {
971		/// Maps a function over the second value in the tuple by reference.
972		#[document_signature]
973		#[document_type_parameters("The lifetime.", "The input type.", "The output type.")]
974		#[document_parameters("The function.", "The tuple.")]
975		#[document_returns("A new tuple with the mapped second value.")]
976		#[document_examples]
977		///
978		/// ```
979		/// use fp_library::{
980		/// 	brands::*,
981		/// 	functions::*,
982		/// };
983		/// assert_eq!(
984		/// 	explicit::map::<Tuple2FirstAppliedBrand<_>, _, _, _, _>(|x: &i32| *x * 2, &(1, 5)),
985		/// 	(1, 10)
986		/// );
987		/// ```
988		fn ref_map<'a, A: 'a, B: 'a>(
989			func: impl Fn(&A) -> B + 'a,
990			fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
991		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
992			(fa.0.clone(), func(&fa.1))
993		}
994	}
995
996	#[document_type_parameters("The type of the first value in the tuple.")]
997	impl<First: Clone + 'static> RefFoldable for Tuple2FirstAppliedBrand<First> {
998		/// Folds the tuple by reference (over second).
999		#[document_signature]
1000		#[document_type_parameters(
1001			"The lifetime.",
1002			"The brand.",
1003			"The element type.",
1004			"The monoid type."
1005		)]
1006		#[document_parameters("The mapping function.", "The tuple.")]
1007		#[document_returns("The monoid value.")]
1008		#[document_examples]
1009		///
1010		/// ```
1011		/// use fp_library::{
1012		/// 	brands::*,
1013		/// 	functions::*,
1014		/// };
1015		/// let result = explicit::fold_map::<RcFnBrand, Tuple2FirstAppliedBrand<()>, _, _, _, _>(
1016		/// 	|x: &i32| x.to_string(),
1017		/// 	&((), 5),
1018		/// );
1019		/// assert_eq!(result, "5");
1020		/// ```
1021		fn ref_fold_map<'a, FnBrand, A: 'a + Clone, M>(
1022			func: impl Fn(&A) -> M + 'a,
1023			fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1024		) -> M
1025		where
1026			FnBrand: LiftFn + 'a,
1027			M: Monoid + 'a, {
1028			func(&fa.1)
1029		}
1030	}
1031
1032	#[document_type_parameters("The type of the first value in the tuple.")]
1033	impl<First: Clone + 'static> RefTraversable for Tuple2FirstAppliedBrand<First> {
1034		/// Traverses the tuple by reference (over second).
1035		#[document_signature]
1036		#[document_type_parameters(
1037			"The lifetime.",
1038			"The brand.",
1039			"The input type.",
1040			"The output type.",
1041			"The applicative."
1042		)]
1043		#[document_parameters("The function.", "The tuple.")]
1044		#[document_returns("The traversed result.")]
1045		#[document_examples]
1046		///
1047		/// ```
1048		/// use fp_library::{
1049		/// 	brands::*,
1050		/// 	functions::*,
1051		/// };
1052		/// let result: Option<((), String)> =
1053		/// 	ref_traverse::<Tuple2FirstAppliedBrand<()>, RcFnBrand, _, _, OptionBrand>(
1054		/// 		|x: &i32| Some(x.to_string()),
1055		/// 		&((), 42),
1056		/// 	);
1057		/// assert_eq!(result, Some(((), "42".to_string())));
1058		/// ```
1059		fn ref_traverse<'a, FnBrand, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
1060			func: impl Fn(&A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1061			ta: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1062		) -> 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>)>)
1063		where
1064			FnBrand: LiftFn + 'a,
1065			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
1066			Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
1067			let first = ta.0.clone();
1068			F::map(move |b| (first.clone(), b), func(&ta.1))
1069		}
1070	}
1071
1072	#[document_type_parameters("The type of the first value in the tuple.")]
1073	impl<First: Clone + 'static> RefPointed for Tuple2FirstAppliedBrand<First>
1074	where
1075		First: Monoid,
1076	{
1077		/// Creates a tuple from a reference by cloning (with empty first).
1078		#[document_signature]
1079		#[document_type_parameters("The lifetime.", "The value type.")]
1080		#[document_parameters("The reference to wrap.")]
1081		#[document_returns("A tuple containing `Monoid::empty()` and a clone of the value.")]
1082		#[document_examples]
1083		///
1084		/// ```
1085		/// use fp_library::{
1086		/// 	brands::*,
1087		/// 	functions::*,
1088		/// };
1089		///
1090		/// let x = 42;
1091		/// let result: (String, i32) = ref_pure::<Tuple2FirstAppliedBrand<String>, _>(&x);
1092		/// assert_eq!(result, ("".to_string(), 42));
1093		/// ```
1094		fn ref_pure<'a, A: Clone + 'a>(
1095			a: &A
1096		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
1097			(Monoid::empty(), a.clone())
1098		}
1099	}
1100
1101	#[document_type_parameters("The type of the first value in the tuple.")]
1102	impl<First: Clone + 'static> RefLift for Tuple2FirstAppliedBrand<First>
1103	where
1104		First: Semigroup,
1105	{
1106		/// Combines two tuples with a by-reference binary function (over second).
1107		#[document_signature]
1108		#[document_type_parameters("The lifetime.", "First input.", "Second input.", "Output.")]
1109		#[document_parameters("The binary function.", "The first tuple.", "The second tuple.")]
1110		#[document_returns("A tuple with combined first values and the function result.")]
1111		#[document_examples]
1112		///
1113		/// ```
1114		/// use fp_library::{
1115		/// 	brands::*,
1116		/// 	functions::*,
1117		/// };
1118		///
1119		/// let result = explicit::lift2::<Tuple2FirstAppliedBrand<String>, _, _, _, _, _, _>(
1120		/// 	|a: &i32, b: &i32| *a + *b,
1121		/// 	&("a".to_string(), 1),
1122		/// 	&("b".to_string(), 2),
1123		/// );
1124		/// assert_eq!(result, ("ab".to_string(), 3));
1125		/// ```
1126		fn ref_lift2<'a, A: 'a, B: 'a, C: 'a>(
1127			func: impl Fn(&A, &B) -> C + 'a,
1128			fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1129			fb: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
1130		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) {
1131			(Semigroup::append(fa.0.clone(), fb.0.clone()), func(&fa.1, &fb.1))
1132		}
1133	}
1134
1135	#[document_type_parameters("The type of the first value in the tuple.")]
1136	impl<First: Clone + 'static> RefSemiapplicative for Tuple2FirstAppliedBrand<First>
1137	where
1138		First: Semigroup,
1139	{
1140		/// Applies a wrapped by-ref function to a tuple value (over second).
1141		#[document_signature]
1142		#[document_type_parameters(
1143			"The lifetime.",
1144			"The function brand.",
1145			"The input type.",
1146			"The output type."
1147		)]
1148		#[document_parameters(
1149			"The tuple containing the function.",
1150			"The tuple containing the value."
1151		)]
1152		#[document_returns("A tuple with combined first values and the function result.")]
1153		#[document_examples]
1154		///
1155		/// ```
1156		/// use fp_library::{
1157		/// 	brands::*,
1158		/// 	functions::*,
1159		/// };
1160		///
1161		/// let f: std::rc::Rc<dyn Fn(&i32) -> i32> = std::rc::Rc::new(|x: &i32| *x * 2);
1162		/// let result = ref_apply::<RcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(
1163		/// 	&("a".to_string(), f),
1164		/// 	&("b".to_string(), 5),
1165		/// );
1166		/// assert_eq!(result, ("ab".to_string(), 10));
1167		/// ```
1168		fn ref_apply<'a, FnBrand: 'a + CloneFn<Ref>, A: 'a, B: 'a>(
1169			ff: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneFn<Ref>>::Of<'a, A, B>>),
1170			fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1171		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1172			(Semigroup::append(ff.0.clone(), fa.0.clone()), (*ff.1)(&fa.1))
1173		}
1174	}
1175
1176	#[document_type_parameters("The type of the first value in the tuple.")]
1177	impl<First: Clone + 'static> RefSemimonad for Tuple2FirstAppliedBrand<First>
1178	where
1179		First: Semigroup,
1180	{
1181		/// Chains tuple computations by reference (over second).
1182		#[document_signature]
1183		#[document_type_parameters("The lifetime.", "The input type.", "The output type.")]
1184		#[document_parameters("The input tuple.", "The function to apply by reference.")]
1185		#[document_returns("A tuple with combined first values.")]
1186		#[document_examples]
1187		///
1188		/// ```
1189		/// use fp_library::{
1190		/// 	brands::*,
1191		/// 	functions::*,
1192		/// };
1193		///
1194		/// let result: (String, String) = explicit::bind::<Tuple2FirstAppliedBrand<String>, _, _, _, _>(
1195		/// 	&("a".to_string(), 42),
1196		/// 	|x: &i32| ("b".to_string(), x.to_string()),
1197		/// );
1198		/// assert_eq!(result, ("ab".to_string(), "42".to_string()));
1199		/// ```
1200		fn ref_bind<'a, A: 'a, B: 'a>(
1201			fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1202			f: impl Fn(&A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1203		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1204			let (next_first, next_second) = f(&fa.1);
1205			(Semigroup::append(fa.0.clone(), next_first), next_second)
1206		}
1207	}
1208
1209	// Tuple2SecondAppliedBrand<Second> (Functor over First)
1210
1211	impl_kind! {
1212		#[multi_brand]
1213		impl<Second: 'static> for Tuple2SecondAppliedBrand<Second> {
1214			type Of<'a, A: 'a>: 'a = (A, Second);
1215		}
1216	}
1217
1218	#[document_type_parameters("The type of the second value in the tuple.")]
1219	impl<Second: 'static> Functor for Tuple2SecondAppliedBrand<Second> {
1220		/// Maps a function over the first value in the tuple.
1221		///
1222		/// 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.
1223		#[document_signature]
1224		///
1225		#[document_type_parameters(
1226			"The lifetime of the values.",
1227			"The type of the first value.",
1228			"The type of the result of applying the function."
1229		)]
1230		///
1231		#[document_parameters(
1232			"The function to apply to the first value.",
1233			"The tuple to map over."
1234		)]
1235		///
1236		#[document_returns(
1237			"A new tuple containing the result of applying the function to the first value."
1238		)]
1239		#[document_examples]
1240		///
1241		/// ```
1242		/// use fp_library::{
1243		/// 	brands::*,
1244		/// 	functions::*,
1245		/// };
1246		///
1247		/// assert_eq!(
1248		/// 	explicit::map::<Tuple2SecondAppliedBrand<_>, _, _, _, _>(|x: i32| x * 2, (5, 1)),
1249		/// 	(10, 1)
1250		/// );
1251		/// ```
1252		fn map<'a, A: 'a, B: 'a>(
1253			func: impl Fn(A) -> B + 'a,
1254			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1255		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1256			(func(fa.0), fa.1)
1257		}
1258	}
1259
1260	#[document_type_parameters("The type of the second value in the tuple.")]
1261	impl<Second: Clone + 'static> Lift for Tuple2SecondAppliedBrand<Second>
1262	where
1263		Second: Semigroup,
1264	{
1265		/// Lifts a binary function into the tuple context (over first).
1266		///
1267		/// 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.
1268		#[document_signature]
1269		///
1270		#[document_type_parameters(
1271			"The lifetime of the values.",
1272			"The type of the first first value.",
1273			"The type of the second first value.",
1274			"The type of the result first value."
1275		)]
1276		///
1277		#[document_parameters(
1278			"The binary function to apply to the first values.",
1279			"The first tuple.",
1280			"The second tuple."
1281		)]
1282		///
1283		#[document_returns(
1284			"A new tuple where the first values are combined using `f` and the second values are combined using `Semigroup::append`."
1285		)]
1286		#[document_examples]
1287		///
1288		/// ```
1289		/// use fp_library::{
1290		/// 	brands::*,
1291		/// 	functions::*,
1292		/// };
1293		///
1294		/// assert_eq!(
1295		/// 	explicit::lift2::<Tuple2SecondAppliedBrand<String>, _, _, _, _, _, _>(
1296		/// 		|x, y| x + y,
1297		/// 		(1, "a".to_string()),
1298		/// 		(2, "b".to_string())
1299		/// 	),
1300		/// 	(3, "ab".to_string())
1301		/// );
1302		/// ```
1303		fn lift2<'a, A, B, C>(
1304			func: impl Fn(A, B) -> C + 'a,
1305			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1306			fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
1307		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
1308		where
1309			A: Clone + 'a,
1310			B: Clone + 'a,
1311			C: 'a, {
1312			(func(fa.0, fb.0), Semigroup::append(fa.1, fb.1))
1313		}
1314	}
1315
1316	#[document_type_parameters("The type of the second value in the tuple.")]
1317	impl<Second: Clone + 'static> Pointed for Tuple2SecondAppliedBrand<Second>
1318	where
1319		Second: Monoid,
1320	{
1321		/// Wraps a value in a tuple (with empty second).
1322		///
1323		/// This method wraps a value in a tuple, using the `Monoid::empty()` value for the second element.
1324		#[document_signature]
1325		///
1326		#[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
1327		///
1328		#[document_parameters("The value to wrap.")]
1329		///
1330		#[document_returns("A tuple containing `a` and the empty value of the second type.")]
1331		///
1332		#[document_examples]
1333		///
1334		/// ```
1335		/// use fp_library::{
1336		/// 	brands::*,
1337		/// 	functions::*,
1338		/// };
1339		///
1340		/// assert_eq!(pure::<Tuple2SecondAppliedBrand<String>, _>(5), (5, "".to_string()));
1341		/// ```
1342		fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
1343			(a, Monoid::empty())
1344		}
1345	}
1346
1347	#[document_type_parameters("The type of the second value in the tuple.")]
1348	impl<Second: Clone + Semigroup + 'static> ApplyFirst for Tuple2SecondAppliedBrand<Second> {}
1349	#[document_type_parameters("The type of the second value in the tuple.")]
1350	impl<Second: Clone + Semigroup + 'static> ApplySecond for Tuple2SecondAppliedBrand<Second> {}
1351
1352	#[document_type_parameters("The type of the second value in the tuple.")]
1353	impl<Second: Clone + 'static> Semiapplicative for Tuple2SecondAppliedBrand<Second>
1354	where
1355		Second: Semigroup,
1356	{
1357		/// Applies a wrapped function to a wrapped value (over first).
1358		///
1359		/// 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.
1360		#[document_signature]
1361		///
1362		#[document_type_parameters(
1363			"The lifetime of the values.",
1364			"The brand of the cloneable function wrapper.",
1365			"The type of the input value.",
1366			"The type of the output value."
1367		)]
1368		///
1369		#[document_parameters(
1370			"The tuple containing the function.",
1371			"The tuple containing the value."
1372		)]
1373		///
1374		#[document_returns(
1375			"A new tuple where the function is applied to the first value and the second values are combined."
1376		)]
1377		#[document_examples]
1378		///
1379		/// ```
1380		/// use fp_library::{
1381		/// 	brands::*,
1382		/// 	classes::semiapplicative::apply as explicit_apply,
1383		/// 	functions::*,
1384		/// };
1385		///
1386		/// let f = (lift_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2), "a".to_string());
1387		/// assert_eq!(
1388		/// 	explicit_apply::<RcFnBrand, Tuple2SecondAppliedBrand<String>, _, _>(
1389		/// 		f,
1390		/// 		(5, "b".to_string())
1391		/// 	),
1392		/// 	(10, "ab".to_string())
1393		/// );
1394		/// ```
1395		fn apply<'a, FnBrand: 'a + CloneFn, A: 'a + Clone, B: 'a>(
1396			ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneFn>::Of<'a, A, B>>),
1397			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1398		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1399			(ff.0(fa.0), Semigroup::append(ff.1, fa.1))
1400		}
1401	}
1402
1403	#[document_type_parameters("The type of the second value in the tuple.")]
1404	impl<Second: Clone + 'static> Semimonad for Tuple2SecondAppliedBrand<Second>
1405	where
1406		Second: Semigroup,
1407	{
1408		/// Chains tuple computations (over first).
1409		///
1410		/// 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.
1411		#[document_signature]
1412		///
1413		#[document_type_parameters(
1414			"The lifetime of the values.",
1415			"The type of the result of the first computation.",
1416			"The type of the result of the second computation."
1417		)]
1418		///
1419		#[document_parameters("The first tuple.", "The function to apply to the first value.")]
1420		///
1421		#[document_returns("A new tuple where the second values are combined.")]
1422		///
1423		#[document_examples]
1424		///
1425		/// ```
1426		/// use fp_library::{
1427		/// 	brands::*,
1428		/// 	functions::*,
1429		/// };
1430		///
1431		/// assert_eq!(
1432		/// 	explicit::bind::<Tuple2SecondAppliedBrand<String>, _, _, _, _>((5, "a".to_string()), |x| (
1433		/// 		x * 2,
1434		/// 		"b".to_string()
1435		/// 	)),
1436		/// 	(10, "ab".to_string())
1437		/// );
1438		/// ```
1439		fn bind<'a, A: 'a, B: 'a>(
1440			ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1441			func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1442		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1443			let (first, second) = ma;
1444			let (next_first, next_second) = func(first);
1445			(next_first, Semigroup::append(second, next_second))
1446		}
1447	}
1448
1449	#[document_type_parameters("The type of the second value in the tuple.")]
1450	impl<Second: Clone + 'static> MonadRec for Tuple2SecondAppliedBrand<Second>
1451	where
1452		Second: Monoid,
1453	{
1454		/// Performs tail-recursive monadic computation over a tuple (varying the first element).
1455		///
1456		/// Iteratively applies the step function, accumulating the second element
1457		/// via `Semigroup::append` at each iteration. When the step function returns
1458		/// `ControlFlow::Break`, the final result and the accumulated second element are returned.
1459		#[document_signature]
1460		///
1461		#[document_type_parameters(
1462			"The lifetime of the computation.",
1463			"The type of the initial value and loop state.",
1464			"The type of the result."
1465		)]
1466		///
1467		#[document_parameters("The step function.", "The initial value.")]
1468		///
1469		#[document_returns(
1470			"A tuple with the result of the computation and the accumulated second value."
1471		)]
1472		///
1473		#[document_examples]
1474		///
1475		/// ```
1476		/// use {
1477		/// 	core::ops::ControlFlow,
1478		/// 	fp_library::{
1479		/// 		brands::*,
1480		/// 		functions::*,
1481		/// 		types::*,
1482		/// 	},
1483		/// };
1484		///
1485		/// let result = tail_rec_m::<Tuple2SecondAppliedBrand<String>, _, _>(
1486		/// 	|n| {
1487		/// 		if n < 3 {
1488		/// 			(ControlFlow::Continue(n + 1), format!("{n},"))
1489		/// 		} else {
1490		/// 			(ControlFlow::Break(n), format!("{n}"))
1491		/// 		}
1492		/// 	},
1493		/// 	0,
1494		/// );
1495		/// assert_eq!(result, (3, "0,1,2,3".to_string()));
1496		/// ```
1497		fn tail_rec_m<'a, A: 'a, B: 'a>(
1498			func: impl Fn(
1499				A,
1500			)
1501				-> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, ControlFlow<B, A>>)
1502			+ 'a,
1503			initial: A,
1504		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1505			let mut acc: Second = Monoid::empty();
1506			let mut current = initial;
1507			loop {
1508				let (step, second) = func(current);
1509				acc = Semigroup::append(acc, second);
1510				match step {
1511					ControlFlow::Continue(next) => current = next,
1512					ControlFlow::Break(b) => return (b, acc),
1513				}
1514			}
1515		}
1516	}
1517
1518	#[document_type_parameters("The type of the second value in the tuple.")]
1519	impl<Second: 'static> Foldable for Tuple2SecondAppliedBrand<Second> {
1520		/// Folds the tuple from the right (over first).
1521		///
1522		/// This method performs a right-associative fold of the tuple (over first).
1523		#[document_signature]
1524		///
1525		#[document_type_parameters(
1526			"The lifetime of the values.",
1527			"The brand of the cloneable function to use.",
1528			"The type of the elements in the structure.",
1529			"The type of the accumulator."
1530		)]
1531		///
1532		#[document_parameters("The folding function.", "The initial value.", "The tuple to fold.")]
1533		///
1534		#[document_returns("`func(a, initial)`.")]
1535		///
1536		#[document_examples]
1537		///
1538		/// ```
1539		/// use fp_library::{
1540		/// 	brands::*,
1541		/// 	functions::*,
1542		/// };
1543		///
1544		/// assert_eq!(
1545		/// 	explicit::fold_right::<RcFnBrand, Tuple2SecondAppliedBrand<()>, _, _, _, _>(
1546		/// 		|x, acc| x + acc,
1547		/// 		0,
1548		/// 		(5, ())
1549		/// 	),
1550		/// 	5
1551		/// );
1552		/// ```
1553		fn fold_right<'a, FnBrand, A: 'a + Clone, B: 'a>(
1554			func: impl Fn(A, B) -> B + 'a,
1555			initial: B,
1556			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1557		) -> B
1558		where
1559			FnBrand: CloneFn + 'a, {
1560			func(fa.0, initial)
1561		}
1562
1563		/// Folds the tuple from the left (over first).
1564		///
1565		/// This method performs a left-associative fold of the tuple (over first).
1566		#[document_signature]
1567		///
1568		#[document_type_parameters(
1569			"The lifetime of the values.",
1570			"The brand of the cloneable function to use.",
1571			"The type of the elements in the structure.",
1572			"The type of the accumulator."
1573		)]
1574		///
1575		#[document_parameters("The folding function.", "The initial value.", "The tuple to fold.")]
1576		///
1577		#[document_returns("`func(initial, a)`.")]
1578		///
1579		#[document_examples]
1580		///
1581		/// ```
1582		/// use fp_library::{
1583		/// 	brands::*,
1584		/// 	functions::*,
1585		/// };
1586		///
1587		/// assert_eq!(
1588		/// 	explicit::fold_left::<RcFnBrand, Tuple2SecondAppliedBrand<()>, _, _, _, _>(
1589		/// 		|acc, x| acc + x,
1590		/// 		0,
1591		/// 		(5, ())
1592		/// 	),
1593		/// 	5
1594		/// );
1595		/// ```
1596		fn fold_left<'a, FnBrand, A: 'a + Clone, B: 'a>(
1597			func: impl Fn(B, A) -> B + 'a,
1598			initial: B,
1599			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1600		) -> B
1601		where
1602			FnBrand: CloneFn + 'a, {
1603			func(initial, fa.0)
1604		}
1605
1606		/// Maps the value to a monoid and returns it (over first).
1607		///
1608		/// This method maps the element of the tuple to a monoid and then returns it (over first).
1609		#[document_signature]
1610		///
1611		#[document_type_parameters(
1612			"The lifetime of the values.",
1613			"The brand of the cloneable function to use.",
1614			"The type of the elements in the structure.",
1615			"The type of the monoid."
1616		)]
1617		///
1618		#[document_parameters("The mapping function.", "The tuple to fold.")]
1619		///
1620		#[document_returns("`func(a)`.")]
1621		///
1622		#[document_examples]
1623		///
1624		/// ```
1625		/// use fp_library::{
1626		/// 	brands::*,
1627		/// 	functions::*,
1628		/// };
1629		///
1630		/// assert_eq!(
1631		/// 	explicit::fold_map::<RcFnBrand, Tuple2SecondAppliedBrand<()>, _, _, _, _>(
1632		/// 		|x: i32| x.to_string(),
1633		/// 		(5, ())
1634		/// 	),
1635		/// 	"5".to_string()
1636		/// );
1637		/// ```
1638		fn fold_map<'a, FnBrand, A: 'a + Clone, M>(
1639			func: impl Fn(A) -> M + 'a,
1640			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1641		) -> M
1642		where
1643			M: Monoid + 'a,
1644			FnBrand: CloneFn + 'a, {
1645			func(fa.0)
1646		}
1647	}
1648
1649	#[document_type_parameters("The type of the second value in the tuple.")]
1650	impl<Second: Clone + 'static> Traversable for Tuple2SecondAppliedBrand<Second> {
1651		/// Traverses the tuple with an applicative function (over first).
1652		///
1653		/// This method maps the element of the tuple to a computation, evaluates it, and combines the result into an applicative context (over first).
1654		#[document_signature]
1655		///
1656		#[document_type_parameters(
1657			"The lifetime of the values.",
1658			"The type of the elements in the traversable structure.",
1659			"The type of the elements in the resulting traversable structure.",
1660			"The applicative context."
1661		)]
1662		///
1663		#[document_parameters("The function to apply.", "The tuple to traverse.")]
1664		///
1665		#[document_returns("The tuple wrapped in the applicative context.")]
1666		///
1667		#[document_examples]
1668		///
1669		/// ```
1670		/// use fp_library::{
1671		/// 	brands::*,
1672		/// 	functions::*,
1673		/// };
1674		///
1675		/// assert_eq!(
1676		/// 	explicit::traverse::<RcFnBrand, Tuple2SecondAppliedBrand<()>, _, _, OptionBrand, _, _>(
1677		/// 		|x| Some(x * 2),
1678		/// 		(5, ())
1679		/// 	),
1680		/// 	Some((10, ()))
1681		/// );
1682		/// ```
1683		fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
1684			func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1685			ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1686		) -> 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>)>)
1687		where
1688			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
1689			let (first, second) = ta;
1690			F::map(move |b| (b, second.clone()), func(first))
1691		}
1692
1693		/// Sequences a tuple of applicative (over first).
1694		///
1695		/// This method evaluates the computation inside the tuple and accumulates the result into an applicative context (over first).
1696		#[document_signature]
1697		///
1698		#[document_type_parameters(
1699			"The lifetime of the values.",
1700			"The type of the elements in the traversable structure.",
1701			"The applicative context."
1702		)]
1703		///
1704		#[document_parameters("The tuple containing the applicative value.")]
1705		///
1706		#[document_returns("The tuple wrapped in the applicative context.")]
1707		///
1708		#[document_examples]
1709		///
1710		/// ```
1711		/// use fp_library::{
1712		/// 	brands::*,
1713		/// 	functions::*,
1714		/// };
1715		///
1716		/// assert_eq!(
1717		/// 	sequence::<Tuple2SecondAppliedBrand<()>, _, OptionBrand>((Some(5), ())),
1718		/// 	Some((5, ()))
1719		/// );
1720		/// ```
1721		fn sequence<'a, A: 'a + Clone, F: Applicative>(
1722			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>)>)
1723		) -> 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>)>)
1724		where
1725			Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
1726			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
1727			let (first, second) = ta;
1728			F::map(move |a| (a, second.clone()), first)
1729		}
1730	}
1731	// -- By-reference trait implementations for Tuple2SecondAppliedBrand --
1732
1733	#[document_type_parameters("The type of the second value in the tuple.")]
1734	impl<Second: Clone + 'static> RefFunctor for Tuple2SecondAppliedBrand<Second> {
1735		/// Maps a function over the first value in the tuple by reference.
1736		#[document_signature]
1737		#[document_type_parameters("The lifetime.", "The input type.", "The output type.")]
1738		#[document_parameters("The function.", "The tuple.")]
1739		#[document_returns("A new tuple with the mapped first value.")]
1740		#[document_examples]
1741		///
1742		/// ```
1743		/// use fp_library::{
1744		/// 	brands::*,
1745		/// 	functions::*,
1746		/// };
1747		/// assert_eq!(
1748		/// 	explicit::map::<Tuple2SecondAppliedBrand<_>, _, _, _, _>(|x: &i32| *x * 2, &(5, 1)),
1749		/// 	(10, 1)
1750		/// );
1751		/// ```
1752		fn ref_map<'a, A: 'a, B: 'a>(
1753			func: impl Fn(&A) -> B + 'a,
1754			fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1755		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1756			(func(&fa.0), fa.1.clone())
1757		}
1758	}
1759
1760	#[document_type_parameters("The type of the second value in the tuple.")]
1761	impl<Second: Clone + 'static> RefFoldable for Tuple2SecondAppliedBrand<Second> {
1762		/// Folds the tuple by reference (over first).
1763		#[document_signature]
1764		#[document_type_parameters(
1765			"The lifetime.",
1766			"The brand.",
1767			"The element type.",
1768			"The monoid type."
1769		)]
1770		#[document_parameters("The mapping function.", "The tuple.")]
1771		#[document_returns("The monoid value.")]
1772		#[document_examples]
1773		///
1774		/// ```
1775		/// use fp_library::{
1776		/// 	brands::*,
1777		/// 	functions::*,
1778		/// };
1779		/// let result = explicit::fold_map::<RcFnBrand, Tuple2SecondAppliedBrand<()>, _, _, _, _>(
1780		/// 	|x: &i32| x.to_string(),
1781		/// 	&(5, ()),
1782		/// );
1783		/// assert_eq!(result, "5");
1784		/// ```
1785		fn ref_fold_map<'a, FnBrand, A: 'a + Clone, M>(
1786			func: impl Fn(&A) -> M + 'a,
1787			fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1788		) -> M
1789		where
1790			FnBrand: LiftFn + 'a,
1791			M: Monoid + 'a, {
1792			func(&fa.0)
1793		}
1794	}
1795
1796	#[document_type_parameters("The type of the second value in the tuple.")]
1797	impl<Second: Clone + 'static> RefTraversable for Tuple2SecondAppliedBrand<Second> {
1798		/// Traverses the tuple by reference (over first).
1799		#[document_signature]
1800		#[document_type_parameters(
1801			"The lifetime.",
1802			"The brand.",
1803			"The input type.",
1804			"The output type.",
1805			"The applicative."
1806		)]
1807		#[document_parameters("The function.", "The tuple.")]
1808		#[document_returns("The traversed result.")]
1809		#[document_examples]
1810		///
1811		/// ```
1812		/// use fp_library::{
1813		/// 	brands::*,
1814		/// 	functions::*,
1815		/// };
1816		/// let result: Option<(String, ())> =
1817		/// 	ref_traverse::<Tuple2SecondAppliedBrand<()>, RcFnBrand, _, _, OptionBrand>(
1818		/// 		|x: &i32| Some(x.to_string()),
1819		/// 		&(42, ()),
1820		/// 	);
1821		/// assert_eq!(result, Some(("42".to_string(), ())));
1822		/// ```
1823		fn ref_traverse<'a, FnBrand, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
1824			func: impl Fn(&A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1825			ta: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1826		) -> 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>)>)
1827		where
1828			FnBrand: LiftFn + 'a,
1829			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone,
1830			Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
1831			let second = ta.1.clone();
1832			F::map(move |a| (a, second.clone()), func(&ta.0))
1833		}
1834	}
1835
1836	#[document_type_parameters("The type of the second value in the tuple.")]
1837	impl<Second: Clone + 'static> RefPointed for Tuple2SecondAppliedBrand<Second>
1838	where
1839		Second: Monoid,
1840	{
1841		/// Creates a tuple from a reference by cloning (with empty second).
1842		#[document_signature]
1843		#[document_type_parameters("The lifetime.", "The value type.")]
1844		#[document_parameters("The reference to wrap.")]
1845		#[document_returns("A tuple containing a clone of the value and `Monoid::empty()`.")]
1846		#[document_examples]
1847		///
1848		/// ```
1849		/// use fp_library::{
1850		/// 	brands::*,
1851		/// 	functions::*,
1852		/// };
1853		///
1854		/// let x = 42;
1855		/// let result: (i32, String) = ref_pure::<Tuple2SecondAppliedBrand<String>, _>(&x);
1856		/// assert_eq!(result, (42, "".to_string()));
1857		/// ```
1858		fn ref_pure<'a, A: Clone + 'a>(
1859			a: &A
1860		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
1861			(a.clone(), Monoid::empty())
1862		}
1863	}
1864
1865	#[document_type_parameters("The type of the second value in the tuple.")]
1866	impl<Second: Clone + 'static> RefLift for Tuple2SecondAppliedBrand<Second>
1867	where
1868		Second: Semigroup,
1869	{
1870		/// Combines two tuples with a by-reference binary function (over first).
1871		#[document_signature]
1872		#[document_type_parameters("The lifetime.", "First input.", "Second input.", "Output.")]
1873		#[document_parameters("The binary function.", "The first tuple.", "The second tuple.")]
1874		#[document_returns("A tuple with the function result and combined second values.")]
1875		#[document_examples]
1876		///
1877		/// ```
1878		/// use fp_library::{
1879		/// 	brands::*,
1880		/// 	functions::*,
1881		/// };
1882		///
1883		/// let result = explicit::lift2::<Tuple2SecondAppliedBrand<String>, _, _, _, _, _, _>(
1884		/// 	|a: &i32, b: &i32| *a + *b,
1885		/// 	&(1, "a".to_string()),
1886		/// 	&(2, "b".to_string()),
1887		/// );
1888		/// assert_eq!(result, (3, "ab".to_string()));
1889		/// ```
1890		fn ref_lift2<'a, A: 'a, B: 'a, C: 'a>(
1891			func: impl Fn(&A, &B) -> C + 'a,
1892			fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1893			fb: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
1894		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) {
1895			(func(&fa.0, &fb.0), Semigroup::append(fa.1.clone(), fb.1.clone()))
1896		}
1897	}
1898
1899	#[document_type_parameters("The type of the second value in the tuple.")]
1900	impl<Second: Clone + 'static> RefSemiapplicative for Tuple2SecondAppliedBrand<Second>
1901	where
1902		Second: Semigroup,
1903	{
1904		/// Applies a wrapped by-ref function to a tuple value (over first).
1905		#[document_signature]
1906		#[document_type_parameters(
1907			"The lifetime.",
1908			"The function brand.",
1909			"The input type.",
1910			"The output type."
1911		)]
1912		#[document_parameters(
1913			"The tuple containing the function.",
1914			"The tuple containing the value."
1915		)]
1916		#[document_returns("A tuple with the function result and combined second values.")]
1917		#[document_examples]
1918		///
1919		/// ```
1920		/// use fp_library::{
1921		/// 	brands::*,
1922		/// 	functions::*,
1923		/// };
1924		///
1925		/// let f: std::rc::Rc<dyn Fn(&i32) -> i32> = std::rc::Rc::new(|x: &i32| *x * 2);
1926		/// let result = ref_apply::<RcFnBrand, Tuple2SecondAppliedBrand<String>, _, _>(
1927		/// 	&(f, "a".to_string()),
1928		/// 	&(5, "b".to_string()),
1929		/// );
1930		/// assert_eq!(result, (10, "ab".to_string()));
1931		/// ```
1932		fn ref_apply<'a, FnBrand: 'a + CloneFn<Ref>, A: 'a, B: 'a>(
1933			ff: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneFn<Ref>>::Of<'a, A, B>>),
1934			fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1935		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1936			((*ff.0)(&fa.0), Semigroup::append(ff.1.clone(), fa.1.clone()))
1937		}
1938	}
1939
1940	#[document_type_parameters("The type of the second value in the tuple.")]
1941	impl<Second: Clone + 'static> RefSemimonad for Tuple2SecondAppliedBrand<Second>
1942	where
1943		Second: Semigroup,
1944	{
1945		/// Chains tuple computations by reference (over first).
1946		#[document_signature]
1947		#[document_type_parameters("The lifetime.", "The input type.", "The output type.")]
1948		#[document_parameters("The input tuple.", "The function to apply by reference.")]
1949		#[document_returns("A tuple with combined second values.")]
1950		#[document_examples]
1951		///
1952		/// ```
1953		/// use fp_library::{
1954		/// 	brands::*,
1955		/// 	functions::*,
1956		/// };
1957		///
1958		/// let result: (String, String) = explicit::bind::<Tuple2SecondAppliedBrand<String>, _, _, _, _>(
1959		/// 	&(42, "a".to_string()),
1960		/// 	|x: &i32| (x.to_string(), "b".to_string()),
1961		/// );
1962		/// assert_eq!(result, ("42".to_string(), "ab".to_string()));
1963		/// ```
1964		fn ref_bind<'a, A: 'a, B: 'a>(
1965			fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
1966			f: impl Fn(&A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
1967		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
1968			let (next_first, next_second) = f(&fa.0);
1969			(next_first, Semigroup::append(fa.1.clone(), next_second))
1970		}
1971	}
1972}
1973
1974#[cfg(test)]
1975mod tests {
1976
1977	use {
1978		crate::{
1979			brands::*,
1980			classes::{
1981				semiapplicative::apply as explicit_apply,
1982				*,
1983			},
1984			functions::*,
1985		},
1986		core::ops::ControlFlow,
1987		quickcheck_macros::quickcheck,
1988	};
1989
1990	// Bifunctor Tests
1991
1992	/// Tests `bimap` on `Tuple2`.
1993	#[test]
1994	fn test_bimap() {
1995		let x = (1, 5);
1996		assert_eq!(
1997			explicit::bimap::<Tuple2Brand, _, _, _, _, _, _>((|a| a + 1, |b| b * 2), x),
1998			(2, 10)
1999		);
2000	}
2001
2002	// Bifunctor Laws
2003
2004	/// Tests the identity law for Bifunctor.
2005	#[quickcheck]
2006	fn bifunctor_identity(
2007		first: String,
2008		second: i32,
2009	) -> bool {
2010		let x = (first, second);
2011		explicit::bimap::<Tuple2Brand, _, _, _, _, _, _>((identity, identity), x.clone()) == x
2012	}
2013
2014	/// Tests the composition law for Bifunctor.
2015	#[quickcheck]
2016	fn bifunctor_composition(
2017		first: i32,
2018		second: i32,
2019	) -> bool {
2020		let x = (first, second);
2021		let f = |x: i32| x.wrapping_add(1);
2022		let g = |x: i32| x.wrapping_mul(2);
2023		let h = |x: i32| x.wrapping_sub(1);
2024		let i = |x: i32| if x == 0 { 0 } else { x.wrapping_div(2) };
2025
2026		explicit::bimap::<Tuple2Brand, _, _, _, _, _, _>((compose(f, g), compose(h, i)), x)
2027			== explicit::bimap::<Tuple2Brand, _, _, _, _, _, _>(
2028				(f, h),
2029				explicit::bimap::<Tuple2Brand, _, _, _, _, _, _>((g, i), x),
2030			)
2031	}
2032
2033	// Functor Laws
2034
2035	/// Tests the identity law for Functor.
2036	#[quickcheck]
2037	fn functor_identity(
2038		first: String,
2039		second: i32,
2040	) -> bool {
2041		let x = (first, second);
2042		explicit::map::<Tuple2FirstAppliedBrand<String>, _, _, _, _>(identity, x.clone()) == x
2043	}
2044
2045	/// Tests the composition law for Functor.
2046	#[quickcheck]
2047	fn functor_composition(
2048		first: String,
2049		second: i32,
2050	) -> bool {
2051		let x = (first, second);
2052		let f = |x: i32| x.wrapping_add(1);
2053		let g = |x: i32| x.wrapping_mul(2);
2054		explicit::map::<Tuple2FirstAppliedBrand<String>, _, _, _, _>(compose(f, g), x.clone())
2055			== explicit::map::<Tuple2FirstAppliedBrand<String>, _, _, _, _>(
2056				f,
2057				explicit::map::<Tuple2FirstAppliedBrand<String>, _, _, _, _>(g, x),
2058			)
2059	}
2060
2061	// Applicative Laws
2062
2063	/// Tests the identity law for Applicative.
2064	#[quickcheck]
2065	fn applicative_identity(
2066		first: String,
2067		second: i32,
2068	) -> bool {
2069		let v = (first, second);
2070		explicit_apply::<RcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(
2071			pure::<Tuple2FirstAppliedBrand<String>, _>(<RcFnBrand as LiftFn>::new(identity)),
2072			v.clone(),
2073		) == v
2074	}
2075
2076	/// Tests the homomorphism law for Applicative.
2077	#[quickcheck]
2078	fn applicative_homomorphism(x: i32) -> bool {
2079		let f = |x: i32| x.wrapping_mul(2);
2080		explicit_apply::<RcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(
2081			pure::<Tuple2FirstAppliedBrand<String>, _>(<RcFnBrand as LiftFn>::new(f)),
2082			pure::<Tuple2FirstAppliedBrand<String>, _>(x),
2083		) == pure::<Tuple2FirstAppliedBrand<String>, _>(f(x))
2084	}
2085
2086	/// Tests the composition law for Applicative.
2087	#[quickcheck]
2088	fn applicative_composition(
2089		w_first: String,
2090		w_second: i32,
2091		u_seed: i32,
2092		v_seed: i32,
2093	) -> bool {
2094		let w = (w_first, w_second);
2095
2096		let u_fn = <RcFnBrand as LiftFn>::new(move |x: i32| x.wrapping_add(u_seed));
2097		let u = pure::<Tuple2FirstAppliedBrand<String>, _>(u_fn);
2098
2099		let v_fn = <RcFnBrand as LiftFn>::new(move |x: i32| x.wrapping_mul(v_seed));
2100		let v = pure::<Tuple2FirstAppliedBrand<String>, _>(v_fn);
2101
2102		// RHS: u <*> (v <*> w)
2103		let vw = explicit_apply::<RcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(
2104			v.clone(),
2105			w.clone(),
2106		);
2107		let rhs = explicit_apply::<RcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(u.clone(), vw);
2108
2109		// LHS: pure(compose) <*> u <*> v <*> w
2110		let compose_fn = <RcFnBrand as LiftFn>::new(|f: std::rc::Rc<dyn Fn(i32) -> i32>| {
2111			let f = f.clone();
2112			<RcFnBrand as LiftFn>::new(move |g: std::rc::Rc<dyn Fn(i32) -> i32>| {
2113				let f = f.clone();
2114				let g = g.clone();
2115				<RcFnBrand as LiftFn>::new(move |x| f(g(x)))
2116			})
2117		});
2118
2119		let pure_compose = pure::<Tuple2FirstAppliedBrand<String>, _>(compose_fn);
2120		let u_applied =
2121			explicit_apply::<RcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(pure_compose, u);
2122		let uv = explicit_apply::<RcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(u_applied, v);
2123		let lhs = explicit_apply::<RcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(uv, w);
2124
2125		lhs == rhs
2126	}
2127
2128	/// Tests the interchange law for Applicative.
2129	#[quickcheck]
2130	fn applicative_interchange(
2131		y: i32,
2132		u_seed: i32,
2133	) -> bool {
2134		// u <*> pure y = pure ($ y) <*> u
2135		let f = move |x: i32| x.wrapping_mul(u_seed);
2136		let u = pure::<Tuple2FirstAppliedBrand<String>, _>(<RcFnBrand as LiftFn>::new(f));
2137
2138		let lhs = explicit_apply::<RcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(
2139			u.clone(),
2140			pure::<Tuple2FirstAppliedBrand<String>, _>(y),
2141		);
2142
2143		let rhs_fn = <RcFnBrand as LiftFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
2144		let rhs = explicit_apply::<RcFnBrand, Tuple2FirstAppliedBrand<String>, _, _>(
2145			pure::<Tuple2FirstAppliedBrand<String>, _>(rhs_fn),
2146			u,
2147		);
2148
2149		lhs == rhs
2150	}
2151
2152	// Monad Laws
2153
2154	/// Tests the left identity law for Monad.
2155	#[quickcheck]
2156	fn monad_left_identity(a: i32) -> bool {
2157		let f = |x: i32| ("f".to_string(), x.wrapping_mul(2));
2158		explicit::bind::<Tuple2FirstAppliedBrand<String>, _, _, _, _>(
2159			pure::<Tuple2FirstAppliedBrand<String>, _>(a),
2160			f,
2161		) == f(a)
2162	}
2163
2164	/// Tests the right identity law for Monad.
2165	#[quickcheck]
2166	fn monad_right_identity(
2167		first: String,
2168		second: i32,
2169	) -> bool {
2170		let m = (first, second);
2171		explicit::bind::<Tuple2FirstAppliedBrand<String>, _, _, _, _>(
2172			m.clone(),
2173			pure::<Tuple2FirstAppliedBrand<String>, _>,
2174		) == m
2175	}
2176
2177	/// Tests the associativity law for Monad.
2178	#[quickcheck]
2179	fn monad_associativity(
2180		first: String,
2181		second: i32,
2182	) -> bool {
2183		let m = (first, second);
2184		let f = |x: i32| ("f".to_string(), x.wrapping_mul(2));
2185		let g = |x: i32| ("g".to_string(), x.wrapping_add(1));
2186		explicit::bind::<Tuple2FirstAppliedBrand<String>, _, _, _, _>(
2187			explicit::bind::<Tuple2FirstAppliedBrand<String>, _, _, _, _>(m.clone(), f),
2188			g,
2189		) == explicit::bind::<Tuple2FirstAppliedBrand<String>, _, _, _, _>(m, |x| {
2190			explicit::bind::<Tuple2FirstAppliedBrand<String>, _, _, _, _>(f(x), g)
2191		})
2192	}
2193
2194	// MonadRec tests (Tuple2FirstAppliedBrand)
2195
2196	/// Tests the MonadRec identity law for Tuple2FirstAppliedBrand:
2197	/// `tail_rec_m(|a| pure(Done(a)), x) == pure(x)`.
2198	#[quickcheck]
2199	fn monad_rec_first_identity(x: i32) -> bool {
2200		tail_rec_m::<Tuple2FirstAppliedBrand<String>, _, _>(
2201			|a| (String::new(), ControlFlow::Break(a)),
2202			x,
2203		) == pure::<Tuple2FirstAppliedBrand<String>, _>(x)
2204	}
2205
2206	/// Tests a recursive computation that accumulates the first element.
2207	#[test]
2208	fn monad_rec_first_accumulation() {
2209		let result = tail_rec_m::<Tuple2FirstAppliedBrand<String>, _, _>(
2210			|n: i32| {
2211				if n < 3 {
2212					(format!("{n},"), ControlFlow::Continue(n + 1))
2213				} else {
2214					(format!("{n}"), ControlFlow::Break(n))
2215				}
2216			},
2217			0,
2218		);
2219		assert_eq!(result, ("0,1,2,3".to_string(), 3));
2220	}
2221
2222	/// Tests stack safety for Tuple2FirstAppliedBrand: `tail_rec_m` handles large iteration counts.
2223	#[test]
2224	fn monad_rec_first_stack_safety() {
2225		let iterations: i64 = 200_000;
2226		let result = tail_rec_m::<Tuple2FirstAppliedBrand<String>, _, _>(
2227			|acc| {
2228				if acc < iterations {
2229					(String::new(), ControlFlow::Continue(acc + 1))
2230				} else {
2231					(String::new(), ControlFlow::Break(acc))
2232				}
2233			},
2234			0i64,
2235		);
2236		assert_eq!(result, (String::new(), iterations));
2237	}
2238
2239	// MonadRec tests (Tuple2SecondAppliedBrand)
2240
2241	/// Tests the MonadRec identity law for Tuple2SecondAppliedBrand:
2242	/// `tail_rec_m(|a| pure(Done(a)), x) == pure(x)`.
2243	#[quickcheck]
2244	fn monad_rec_second_identity(x: i32) -> bool {
2245		tail_rec_m::<Tuple2SecondAppliedBrand<String>, _, _>(
2246			|a| (ControlFlow::Break(a), String::new()),
2247			x,
2248		) == pure::<Tuple2SecondAppliedBrand<String>, _>(x)
2249	}
2250
2251	/// Tests a recursive computation that accumulates the second element.
2252	#[test]
2253	fn monad_rec_second_accumulation() {
2254		let result = tail_rec_m::<Tuple2SecondAppliedBrand<String>, _, _>(
2255			|n: i32| {
2256				if n < 3 {
2257					(ControlFlow::Continue(n + 1), format!("{n},"))
2258				} else {
2259					(ControlFlow::Break(n), format!("{n}"))
2260				}
2261			},
2262			0,
2263		);
2264		assert_eq!(result, (3, "0,1,2,3".to_string()));
2265	}
2266
2267	/// Tests stack safety for Tuple2SecondAppliedBrand: `tail_rec_m` handles large iteration counts.
2268	#[test]
2269	fn monad_rec_second_stack_safety() {
2270		let iterations: i64 = 200_000;
2271		let result = tail_rec_m::<Tuple2SecondAppliedBrand<String>, _, _>(
2272			|acc| {
2273				if acc < iterations {
2274					(ControlFlow::Continue(acc + 1), String::new())
2275				} else {
2276					(ControlFlow::Break(acc), String::new())
2277				}
2278			},
2279			0i64,
2280		);
2281		assert_eq!(result, (iterations, String::new()));
2282	}
2283}