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