Skip to main content

fp_library/types/
identity.rs

1//! Trivial wrapper that contains a single value.
2//!
3//! The simplest possible container type, often used as a base case for higher-kinded types or when a container is required but no additional effect is needed.
4
5#[fp_macros::document_module]
6mod inner {
7	use {
8		crate::{
9			Apply,
10			brands::IdentityBrand,
11			classes::{
12				Applicative,
13				ApplyFirst,
14				ApplySecond,
15				CloneableFn,
16				Foldable,
17				Functor,
18				Lift,
19				Monoid,
20				ParFoldable,
21				Pointed,
22				Semiapplicative,
23				Semimonad,
24				SendCloneableFn,
25				Traversable,
26			},
27			impl_kind,
28			kinds::*,
29		},
30		fp_macros::*,
31	};
32
33	/// Wraps a value.
34	///
35	/// The `Identity` type represents a trivial wrapper around a value. It is the simplest possible container.
36	/// It is often used as a base case for higher-kinded types or when a container is required but no additional effect is needed.
37	///
38	/// ### Higher-Kinded Type Representation
39	///
40	/// The higher-kinded representation of this type constructor is [`IdentityBrand`](crate::brands::IdentityBrand),
41	/// which is fully polymorphic over the wrapped value type.
42	///
43	/// ### Serialization
44	///
45	/// This type supports serialization and deserialization via [`serde`](https://serde.rs) when the `serde` feature is enabled.
46	#[document_type_parameters("The type of the wrapped value.")]
47	///
48	#[document_fields("The wrapped value.")]
49	///
50	#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
51	#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
52	pub struct Identity<A>(pub A);
53
54	impl_kind! {
55		for IdentityBrand {
56			type Of<'a, A: 'a>: 'a = Identity<A>;
57		}
58	}
59
60	#[document_type_parameters("The type of the wrapped value.")]
61	#[document_parameters("The identity instance.")]
62	impl<A> Identity<A> {
63		/// Maps a function over the value in the identity.
64		///
65		/// This is the inherent version of [`Functor::map`], accepting
66		/// `FnOnce` instead of `Fn` since it consumes `self`.
67		#[document_signature]
68		///
69		#[document_type_parameters("The type of the result of applying the function.")]
70		///
71		#[document_parameters("The function to apply.")]
72		///
73		#[document_returns("A new identity containing the result of applying the function.")]
74		///
75		#[document_examples]
76		///
77		/// ```
78		/// use fp_library::types::*;
79		///
80		/// let x = Identity(5);
81		/// let y = x.map(|i| i * 2);
82		/// assert_eq!(y, Identity(10));
83		/// ```
84		pub fn map<B>(
85			self,
86			f: impl FnOnce(A) -> B,
87		) -> Identity<B> {
88			Identity(f(self.0))
89		}
90
91		/// Lifts a binary function to operate on two identities.
92		///
93		/// See [`Lift::lift2`] for the type class version.
94		#[document_signature]
95		///
96		#[document_type_parameters(
97			"The type of the other identity's value.",
98			"The return type of the function."
99		)]
100		///
101		#[document_parameters("The other identity.", "The binary function to apply.")]
102		///
103		#[document_returns("A new identity containing the result of applying the function.")]
104		///
105		#[document_examples]
106		///
107		/// ```
108		/// use fp_library::types::*;
109		///
110		/// let x = Identity(1);
111		/// let y = Identity(2);
112		/// let z = x.lift2(y, |a, b| a + b);
113		/// assert_eq!(z, Identity(3));
114		/// ```
115		pub fn lift2<B, C>(
116			self,
117			other: Identity<B>,
118			f: impl FnOnce(A, B) -> C,
119		) -> Identity<C> {
120			Identity(f(self.0, other.0))
121		}
122
123		/// Applies a wrapped function to a value.
124		///
125		/// See [`Semiapplicative::apply`] for the type class version.
126		#[document_signature]
127		///
128		#[document_type_parameters("The return type of the wrapped function.")]
129		///
130		#[document_parameters("The identity containing the function.")]
131		///
132		#[document_returns("A new identity containing the result.")]
133		///
134		#[document_examples]
135		///
136		/// ```
137		/// use fp_library::types::*;
138		///
139		/// let f = Identity(|x: i32| x * 2);
140		/// let x = Identity(5);
141		/// let y = x.apply(f);
142		/// assert_eq!(y, Identity(10));
143		/// ```
144		pub fn apply<B>(
145			self,
146			ff: Identity<impl FnOnce(A) -> B>,
147		) -> Identity<B> {
148			Identity(ff.0(self.0))
149		}
150
151		/// Chains identity computations.
152		///
153		/// This is the inherent version of [`Semimonad::bind`], accepting
154		/// `FnOnce` instead of `Fn` since it consumes `self`.
155		#[document_signature]
156		///
157		#[document_type_parameters("The type of the result of the chained computation.")]
158		///
159		#[document_parameters("The function to apply to the value inside the identity.")]
160		///
161		#[document_returns("The result of applying `f` to the value.")]
162		///
163		#[document_examples]
164		///
165		/// ```
166		/// use fp_library::types::*;
167		///
168		/// let x = Identity(5);
169		/// let y = x.bind(|i| Identity(i * 2));
170		/// assert_eq!(y, Identity(10));
171		/// ```
172		pub fn bind<B>(
173			self,
174			f: impl FnOnce(A) -> Identity<B>,
175		) -> Identity<B> {
176			f(self.0)
177		}
178
179		/// Folds the identity from the right.
180		///
181		/// See [`Foldable::fold_right`] for the type class version.
182		#[document_signature]
183		///
184		#[document_type_parameters("The type of the accumulator.")]
185		///
186		#[document_parameters(
187			"The function to apply to the element and the accumulator.",
188			"The initial value of the accumulator."
189		)]
190		///
191		#[document_returns("The final accumulator value.")]
192		///
193		#[document_examples]
194		///
195		/// ```
196		/// use fp_library::types::*;
197		///
198		/// let x = Identity(5);
199		/// let y = x.fold_right(|a, b| a + b, 10);
200		/// assert_eq!(y, 15);
201		/// ```
202		pub fn fold_right<B>(
203			self,
204			f: impl FnOnce(A, B) -> B,
205			initial: B,
206		) -> B {
207			f(self.0, initial)
208		}
209
210		/// Folds the identity from the left.
211		///
212		/// See [`Foldable::fold_left`] for the type class version.
213		#[document_signature]
214		///
215		#[document_type_parameters("The type of the accumulator.")]
216		///
217		#[document_parameters(
218			"The function to apply to the accumulator and the element.",
219			"The initial value of the accumulator."
220		)]
221		///
222		#[document_returns("The final accumulator value.")]
223		///
224		#[document_examples]
225		///
226		/// ```
227		/// use fp_library::types::*;
228		///
229		/// let x = Identity(5);
230		/// let y = x.fold_left(|b, a| b + a, 10);
231		/// assert_eq!(y, 15);
232		/// ```
233		pub fn fold_left<B>(
234			self,
235			f: impl FnOnce(B, A) -> B,
236			initial: B,
237		) -> B {
238			f(initial, self.0)
239		}
240
241		/// Maps the value to a monoid and returns it.
242		///
243		/// See [`Foldable::fold_map`] for the type class version.
244		#[document_signature]
245		///
246		#[document_type_parameters("The monoid type.")]
247		///
248		#[document_parameters("The mapping function.")]
249		///
250		#[document_returns("The monoid value.")]
251		///
252		#[document_examples]
253		///
254		/// ```
255		/// use fp_library::types::*;
256		///
257		/// let x = Identity(5);
258		/// let y = x.fold_map(|a: i32| a.to_string());
259		/// assert_eq!(y, "5".to_string());
260		/// ```
261		pub fn fold_map<M>(
262			self,
263			f: impl FnOnce(A) -> M,
264		) -> M {
265			f(self.0)
266		}
267	}
268
269	#[document_type_parameters("The lifetime of the values.", "The type of the wrapped value.")]
270	#[document_parameters("The identity instance.")]
271	impl<'a, A: 'a> Identity<A> {
272		/// Traverses the identity with an applicative function.
273		///
274		/// See [`Traversable::traverse`] for the type class version.
275		#[document_signature]
276		///
277		#[document_type_parameters(
278			"The type of the elements in the resulting identity.",
279			"The applicative context."
280		)]
281		///
282		#[document_parameters(
283			"The function to apply, returning a value in an applicative context."
284		)]
285		///
286		#[document_returns("The identity wrapped in the applicative context.")]
287		///
288		#[document_examples]
289		///
290		/// ```
291		/// use fp_library::{
292		/// 	brands::*,
293		/// 	types::*,
294		/// };
295		///
296		/// let x = Identity(5);
297		/// let y = x.traverse::<_, OptionBrand>(|a| Some(a * 2));
298		/// assert_eq!(y, Some(Identity(10)));
299		/// ```
300		pub fn traverse<B: 'a + Clone, F: Applicative>(
301			self,
302			f: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
303		) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Identity<B>>)
304		where
305			Identity<B>: Clone, {
306			F::map(|b| Identity(b), f(self.0))
307		}
308
309		/// Sequences an identity containing an applicative value.
310		///
311		/// See [`Traversable::sequence`] for the type class version.
312		#[document_signature]
313		///
314		#[document_type_parameters(
315			"The inner type wrapped in the applicative context.",
316			"The applicative context."
317		)]
318		///
319		#[document_returns("The identity wrapped in the applicative context.")]
320		///
321		#[document_examples]
322		///
323		/// ```
324		/// use fp_library::{
325		/// 	brands::*,
326		/// 	types::*,
327		/// };
328		///
329		/// let x = Identity(Some(5));
330		/// let y: Option<Identity<i32>> = x.sequence::<i32, OptionBrand>();
331		/// assert_eq!(y, Some(Identity(5)));
332		/// ```
333		pub fn sequence<InnerA: 'a + Clone, F: Applicative>(
334			self
335		) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Identity<InnerA>>)
336		where
337			A: Into<Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, InnerA>)>,
338			Identity<InnerA>: Clone, {
339			F::map(|a| Identity(a), self.0.into())
340		}
341	}
342
343	impl Functor for IdentityBrand {
344		/// Maps a function over the value in the identity.
345		///
346		/// This method applies a function to the value inside the identity, producing a new identity with the transformed value.
347		#[document_signature]
348		///
349		#[document_type_parameters(
350			"The lifetime of the value.",
351			"The type of the value inside the identity.",
352			"The type of the result of applying the function."
353		)]
354		///
355		#[document_parameters("The function to apply.", "The identity to map over.")]
356		///
357		#[document_returns("A new identity containing the result of applying the function.")]
358		///
359		#[document_examples]
360		///
361		/// ```
362		/// use fp_library::{
363		/// 	brands::*,
364		/// 	functions::*,
365		/// 	types::*,
366		/// };
367		///
368		/// let x = Identity(5);
369		/// let y = map::<IdentityBrand, _, _>(|i| i * 2, x);
370		/// assert_eq!(y, Identity(10));
371		/// ```
372		fn map<'a, A: 'a, B: 'a>(
373			func: impl Fn(A) -> B + 'a,
374			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
375		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
376			fa.map(func)
377		}
378	}
379
380	impl Lift for IdentityBrand {
381		/// Lifts a binary function into the identity context.
382		///
383		/// This method lifts a binary function to operate on values within the identity context.
384		#[document_signature]
385		///
386		#[document_type_parameters(
387			"The lifetime of the values.",
388			"The type of the first identity's value.",
389			"The type of the second identity's value.",
390			"The return type of the function."
391		)]
392		///
393		#[document_parameters(
394			"The binary function to apply.",
395			"The first identity.",
396			"The second identity."
397		)]
398		///
399		#[document_returns("A new identity containing the result of applying the function.")]
400		#[document_examples]
401		///
402		/// ```
403		/// use fp_library::{
404		/// 	brands::*,
405		/// 	functions::*,
406		/// 	types::*,
407		/// };
408		///
409		/// let x = Identity(1);
410		/// let y = Identity(2);
411		/// let z = lift2::<IdentityBrand, _, _, _>(|a, b| a + b, x, y);
412		/// assert_eq!(z, Identity(3));
413		/// ```
414		fn lift2<'a, A, B, C>(
415			func: impl Fn(A, B) -> C + 'a,
416			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
417			fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
418		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
419		where
420			A: 'a,
421			B: 'a,
422			C: 'a, {
423			fa.lift2(fb, func)
424		}
425	}
426
427	impl Pointed for IdentityBrand {
428		/// Wraps a value in an identity.
429		///
430		/// This method wraps a value in an identity context.
431		#[document_signature]
432		///
433		#[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
434		///
435		#[document_parameters("The value to wrap.")]
436		///
437		#[document_returns("An identity containing the value.")]
438		///
439		#[document_examples]
440		///
441		/// ```
442		/// use fp_library::{
443		/// 	brands::*,
444		/// 	functions::*,
445		/// 	types::*,
446		/// };
447		///
448		/// let x = pure::<IdentityBrand, _>(5);
449		/// assert_eq!(x, Identity(5));
450		/// ```
451		fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
452			Identity(a) // Identity constructor is already equivalent to pure
453		}
454	}
455
456	impl ApplyFirst for IdentityBrand {}
457	impl ApplySecond for IdentityBrand {}
458
459	impl Semiapplicative for IdentityBrand {
460		/// Applies a wrapped function to a wrapped value.
461		///
462		/// This method applies a function wrapped in an identity to a value wrapped in an identity.
463		#[document_signature]
464		///
465		#[document_type_parameters(
466			"The lifetime of the values.",
467			"The brand of the cloneable function wrapper.",
468			"The type of the input value.",
469			"The type of the output value."
470		)]
471		///
472		#[document_parameters(
473			"The identity containing the function.",
474			"The identity containing the value."
475		)]
476		///
477		#[document_returns("A new identity containing the result of applying the function.")]
478		#[document_examples]
479		///
480		/// ```
481		/// use fp_library::{
482		/// 	brands::*,
483		/// 	functions::*,
484		/// 	types::*,
485		/// };
486		///
487		/// let f = Identity(cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2));
488		/// let x = Identity(5);
489		/// let y = apply::<RcFnBrand, IdentityBrand, _, _>(f, x);
490		/// assert_eq!(y, Identity(10));
491		/// ```
492		fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
493			ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
494			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
495		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
496			fa.apply(ff.map(|f| move |a| f(a)))
497		}
498	}
499
500	impl Semimonad for IdentityBrand {
501		/// Chains identity computations.
502		///
503		/// This method chains two identity computations, where the second computation depends on the result of the first.
504		#[document_signature]
505		///
506		#[document_type_parameters(
507			"The lifetime of the values.",
508			"The type of the result of the first computation.",
509			"The type of the result of the second computation."
510		)]
511		///
512		#[document_parameters(
513			"The first identity.",
514			"The function to apply to the value inside the identity."
515		)]
516		///
517		#[document_returns("The result of applying `f` to the value.")]
518		#[document_examples]
519		///
520		/// ```
521		/// use fp_library::{
522		/// 	brands::*,
523		/// 	functions::*,
524		/// 	types::*,
525		/// };
526		///
527		/// let x = Identity(5);
528		/// let y = bind::<IdentityBrand, _, _>(x, |i| Identity(i * 2));
529		/// assert_eq!(y, Identity(10));
530		/// ```
531		fn bind<'a, A: 'a, B: 'a>(
532			ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
533			func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
534		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
535			ma.bind(func)
536		}
537	}
538
539	impl Foldable for IdentityBrand {
540		/// Folds the identity from the right.
541		///
542		/// This method performs a right-associative fold of the identity. Since `Identity` contains only one element, this is equivalent to applying the function to the element and the initial value.
543		#[document_signature]
544		///
545		#[document_type_parameters(
546			"The lifetime of the values.",
547			"The brand of the cloneable function to use.",
548			"The type of the elements in the structure.",
549			"The type of the accumulator."
550		)]
551		///
552		#[document_parameters(
553			"The function to apply to each element and the accumulator.",
554			"The initial value of the accumulator.",
555			"The identity to fold."
556		)]
557		///
558		#[document_returns("The final accumulator value.")]
559		#[document_examples]
560		///
561		/// ```
562		/// use fp_library::{
563		/// 	brands::*,
564		/// 	functions::*,
565		/// 	types::*,
566		/// };
567		///
568		/// let x = Identity(5);
569		/// let y = fold_right::<RcFnBrand, IdentityBrand, _, _>(|a, b| a + b, 10, x);
570		/// assert_eq!(y, 15);
571		/// ```
572		fn fold_right<'a, FnBrand, A: 'a, B: 'a>(
573			func: impl Fn(A, B) -> B + 'a,
574			initial: B,
575			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
576		) -> B
577		where
578			FnBrand: CloneableFn + 'a, {
579			fa.fold_right(func, initial)
580		}
581
582		/// Folds the identity from the left.
583		///
584		/// This method performs a left-associative fold of the identity. Since `Identity` contains only one element, this is equivalent to applying the function to the initial value and the element.
585		#[document_signature]
586		///
587		#[document_type_parameters(
588			"The lifetime of the values.",
589			"The brand of the cloneable function to use.",
590			"The type of the elements in the structure.",
591			"The type of the accumulator."
592		)]
593		///
594		#[document_parameters(
595			"The function to apply to the accumulator and each element.",
596			"The initial value of the accumulator.",
597			"The structure to fold."
598		)]
599		///
600		#[document_returns("The final accumulator value.")]
601		#[document_examples]
602		///
603		/// ```
604		/// use fp_library::{
605		/// 	brands::*,
606		/// 	functions::*,
607		/// 	types::*,
608		/// };
609		///
610		/// let x = Identity(5);
611		/// let y = fold_left::<RcFnBrand, IdentityBrand, _, _>(|b, a| b + a, 10, x);
612		/// assert_eq!(y, 15);
613		/// ```
614		fn fold_left<'a, FnBrand, A: 'a, B: 'a>(
615			func: impl Fn(B, A) -> B + 'a,
616			initial: B,
617			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
618		) -> B
619		where
620			FnBrand: CloneableFn + 'a, {
621			fa.fold_left(func, initial)
622		}
623
624		/// Maps the value to a monoid and returns it.
625		///
626		/// This method maps the element of the identity to a monoid.
627		#[document_signature]
628		///
629		#[document_type_parameters(
630			"The lifetime of the values.",
631			"The brand of the cloneable function to use.",
632			"The type of the elements in the structure.",
633			"The type of the monoid."
634		)]
635		///
636		#[document_parameters("The mapping function.", "The identity to fold.")]
637		///
638		#[document_returns("The monoid value.")]
639		///
640		#[document_examples]
641		///
642		/// ```
643		/// use fp_library::{
644		/// 	brands::*,
645		/// 	functions::*,
646		/// 	types::*,
647		/// };
648		///
649		/// let x = Identity(5);
650		/// let y = fold_map::<RcFnBrand, IdentityBrand, _, _>(|a: i32| a.to_string(), x);
651		/// assert_eq!(y, "5".to_string());
652		/// ```
653		fn fold_map<'a, FnBrand, A: 'a, M>(
654			func: impl Fn(A) -> M + 'a,
655			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
656		) -> M
657		where
658			M: Monoid + 'a,
659			FnBrand: CloneableFn + 'a, {
660			fa.fold_map(func)
661		}
662	}
663
664	impl Traversable for IdentityBrand {
665		/// Traverses the identity with an applicative function.
666		///
667		/// This method maps the element of the identity to a computation, evaluates it, and wraps the result in the applicative context.
668		#[document_signature]
669		///
670		#[document_type_parameters(
671			"The lifetime of the values.",
672			"The type of the elements in the traversable structure.",
673			"The type of the elements in the resulting traversable structure.",
674			"The applicative context."
675		)]
676		///
677		#[document_parameters(
678			"The function to apply to each element, returning a value in an applicative context.",
679			"The identity to traverse."
680		)]
681		///
682		#[document_returns("The identity wrapped in the applicative context.")]
683		#[document_examples]
684		///
685		/// ```
686		/// use fp_library::{
687		/// 	brands::*,
688		/// 	functions::*,
689		/// 	types::*,
690		/// };
691		///
692		/// let x = Identity(5);
693		/// let y = traverse::<IdentityBrand, _, _, OptionBrand>(|a| Some(a * 2), x);
694		/// assert_eq!(y, Some(Identity(10)));
695		/// ```
696		fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
697			func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
698			ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
699		) -> 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>)>)
700		where
701			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
702			ta.traverse::<B, F>(func)
703		}
704
705		/// Sequences an identity of applicative.
706		///
707		/// This method evaluates the computation inside the identity and wraps the result in the applicative context.
708		#[document_signature]
709		///
710		#[document_type_parameters(
711			"The lifetime of the values.",
712			"The type of the elements in the traversable structure.",
713			"The applicative context."
714		)]
715		///
716		#[document_parameters("The identity containing the applicative value.")]
717		///
718		#[document_returns("The result of the traversal.")]
719		///
720		/// # Returns
721		///
722		/// The identity wrapped in the applicative context.
723		#[document_examples]
724		///
725		/// ```
726		/// use fp_library::{
727		/// 	brands::*,
728		/// 	functions::*,
729		/// 	types::*,
730		/// };
731		///
732		/// let x = Identity(Some(5));
733		/// let y = sequence::<IdentityBrand, _, OptionBrand>(x);
734		/// assert_eq!(y, Some(Identity(5)));
735		/// ```
736		fn sequence<'a, A: 'a + Clone, F: Applicative>(
737			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>)>)
738		) -> 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>)>)
739		where
740			Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
741			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
742			ta.traverse::<A, F>(|a| a)
743		}
744	}
745
746	impl ParFoldable for IdentityBrand {
747		/// Maps the value to a monoid and returns it in parallel.
748		///
749		/// This method maps the element of the identity to a monoid. Since `Identity` contains only one element, no actual parallelism occurs, but the interface is satisfied.
750		#[document_signature]
751		///
752		#[document_type_parameters(
753			"The lifetime of the values.",
754			"The brand of the cloneable function wrapper.",
755			"The element type.",
756			"The monoid type."
757		)]
758		///
759		#[document_parameters("The mapping function.", "The identity to fold.")]
760		///
761		#[document_returns("The combined monoid value.")]
762		///
763		#[document_examples]
764		///
765		/// ```
766		/// use fp_library::{
767		/// 	brands::*,
768		/// 	functions::*,
769		/// 	types::*,
770		/// };
771		///
772		/// let x = Identity(1);
773		/// let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
774		/// let y = par_fold_map::<ArcFnBrand, IdentityBrand, _, _>(f, x);
775		/// assert_eq!(y, "1".to_string());
776		/// ```
777		fn par_fold_map<'a, FnBrand, A, M>(
778			func: <FnBrand as SendCloneableFn>::SendOf<'a, A, M>,
779			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
780		) -> M
781		where
782			FnBrand: 'a + SendCloneableFn,
783			A: 'a + Clone + Send + Sync,
784			M: Monoid + Send + Sync + 'a, {
785			func(fa.0)
786		}
787
788		/// Folds the identity from the right in parallel.
789		///
790		/// This method performs a right-associative fold of the identity. Since `Identity` contains only one element, no actual parallelism occurs.
791		#[document_signature]
792		///
793		#[document_type_parameters(
794			"The lifetime of the values.",
795			"The brand of the cloneable function wrapper.",
796			"The element type.",
797			"The accumulator type."
798		)]
799		///
800		#[document_parameters(
801			"The thread-safe function to apply to each element and the accumulator.",
802			"The initial value of the accumulator.",
803			"The identity to fold."
804		)]
805		///
806		#[document_returns("The final accumulator value.")]
807		#[document_examples]
808		///
809		/// ```
810		/// use fp_library::{
811		/// 	brands::*,
812		/// 	functions::*,
813		/// 	types::*,
814		/// };
815		///
816		/// let x = Identity(1);
817		/// let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
818		/// let y = par_fold_right::<ArcFnBrand, IdentityBrand, _, _>(f, 10, x);
819		/// assert_eq!(y, 11);
820		/// ```
821		fn par_fold_right<'a, FnBrand, A, B>(
822			func: <FnBrand as SendCloneableFn>::SendOf<'a, (A, B), B>,
823			initial: B,
824			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
825		) -> B
826		where
827			FnBrand: 'a + SendCloneableFn,
828			A: 'a + Clone + Send + Sync,
829			B: Send + Sync + 'a, {
830			func((fa.0, initial))
831		}
832	}
833}
834pub use inner::*;
835
836#[cfg(test)]
837mod tests {
838	use {
839		super::inner::Identity,
840		crate::{
841			brands::{
842				IdentityBrand,
843				OptionBrand,
844				RcFnBrand,
845			},
846			classes::{
847				cloneable_fn::CloneableFn,
848				functor::map,
849				pointed::pure,
850				semiapplicative::apply,
851				semimonad::bind,
852			},
853			functions::{
854				compose,
855				identity,
856			},
857		},
858		quickcheck_macros::quickcheck,
859	};
860
861	// Functor Laws
862
863	/// Tests the identity law for Functor.
864	#[quickcheck]
865	fn functor_identity(x: i32) -> bool {
866		let x = Identity(x);
867		map::<IdentityBrand, _, _>(identity, x) == x
868	}
869
870	/// Tests the composition law for Functor.
871	#[quickcheck]
872	fn functor_composition(x: i32) -> bool {
873		let x = Identity(x);
874		let f = |x: i32| x.wrapping_add(1);
875		let g = |x: i32| x.wrapping_mul(2);
876		map::<IdentityBrand, _, _>(compose(f, g), x)
877			== map::<IdentityBrand, _, _>(f, map::<IdentityBrand, _, _>(g, x))
878	}
879
880	// Applicative Laws
881
882	/// Tests the identity law for Applicative.
883	#[quickcheck]
884	fn applicative_identity(v: i32) -> bool {
885		let v = Identity(v);
886		apply::<RcFnBrand, IdentityBrand, _, _>(
887			pure::<IdentityBrand, _>(<RcFnBrand as CloneableFn>::new(identity)),
888			v,
889		) == v
890	}
891
892	/// Tests the homomorphism law for Applicative.
893	#[quickcheck]
894	fn applicative_homomorphism(x: i32) -> bool {
895		let f = |x: i32| x.wrapping_mul(2);
896		apply::<RcFnBrand, IdentityBrand, _, _>(
897			pure::<IdentityBrand, _>(<RcFnBrand as CloneableFn>::new(f)),
898			pure::<IdentityBrand, _>(x),
899		) == pure::<IdentityBrand, _>(f(x))
900	}
901
902	/// Tests the composition law for Applicative.
903	#[quickcheck]
904	fn applicative_composition(
905		w: i32,
906		u_val: i32,
907		v_val: i32,
908	) -> bool {
909		let w = Identity(w);
910		let v_fn = move |x: i32| x.wrapping_mul(v_val);
911		let u_fn = move |x: i32| x.wrapping_add(u_val);
912
913		let v = pure::<IdentityBrand, _>(<RcFnBrand as CloneableFn>::new(v_fn));
914		let u = pure::<IdentityBrand, _>(<RcFnBrand as CloneableFn>::new(u_fn));
915
916		// RHS: u <*> (v <*> w)
917		let vw = apply::<RcFnBrand, IdentityBrand, _, _>(v.clone(), w);
918		let rhs = apply::<RcFnBrand, IdentityBrand, _, _>(u.clone(), vw);
919
920		// LHS: pure(compose) <*> u <*> v <*> w
921		// equivalent to (u . v) <*> w
922		let composed = move |x| u_fn(v_fn(x));
923		let uv = pure::<IdentityBrand, _>(<RcFnBrand as CloneableFn>::new(composed));
924
925		let lhs = apply::<RcFnBrand, IdentityBrand, _, _>(uv, w);
926
927		lhs == rhs
928	}
929
930	/// Tests the interchange law for Applicative.
931	#[quickcheck]
932	fn applicative_interchange(y: i32) -> bool {
933		// u <*> pure y = pure ($ y) <*> u
934		let f = |x: i32| x.wrapping_mul(2);
935		let u = pure::<IdentityBrand, _>(<RcFnBrand as CloneableFn>::new(f));
936
937		let lhs = apply::<RcFnBrand, IdentityBrand, _, _>(u.clone(), pure::<IdentityBrand, _>(y));
938
939		let rhs_fn =
940			<RcFnBrand as CloneableFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
941		let rhs = apply::<RcFnBrand, IdentityBrand, _, _>(pure::<IdentityBrand, _>(rhs_fn), u);
942
943		lhs == rhs
944	}
945
946	// Monad Laws
947
948	/// Tests the left identity law for Monad.
949	#[quickcheck]
950	fn monad_left_identity(a: i32) -> bool {
951		let f = |x: i32| Identity(x.wrapping_mul(2));
952		bind::<IdentityBrand, _, _>(pure::<IdentityBrand, _>(a), f) == f(a)
953	}
954
955	/// Tests the right identity law for Monad.
956	#[quickcheck]
957	fn monad_right_identity(m: i32) -> bool {
958		let m = Identity(m);
959		bind::<IdentityBrand, _, _>(m, pure::<IdentityBrand, _>) == m
960	}
961
962	/// Tests the associativity law for Monad.
963	#[quickcheck]
964	fn monad_associativity(m: i32) -> bool {
965		let m = Identity(m);
966		let f = |x: i32| Identity(x.wrapping_mul(2));
967		let g = |x: i32| Identity(x.wrapping_add(1));
968		bind::<IdentityBrand, _, _>(bind::<IdentityBrand, _, _>(m, f), g)
969			== bind::<IdentityBrand, _, _>(m, |x| bind::<IdentityBrand, _, _>(f(x), g))
970	}
971
972	// Edge Cases
973
974	/// Tests the `map` function.
975	#[test]
976	fn map_test() {
977		assert_eq!(map::<IdentityBrand, _, _>(|x: i32| x + 1, Identity(1)), Identity(2));
978	}
979
980	/// Tests the `bind` function.
981	#[test]
982	fn bind_test() {
983		assert_eq!(bind::<IdentityBrand, _, _>(Identity(1), |x| Identity(x + 1)), Identity(2));
984	}
985
986	/// Tests the `fold_right` function.
987	#[test]
988	fn fold_right_test() {
989		assert_eq!(
990			crate::classes::foldable::fold_right::<RcFnBrand, IdentityBrand, _, _>(
991				|x: i32, acc| x + acc,
992				0,
993				Identity(1)
994			),
995			1
996		);
997	}
998
999	/// Tests the `fold_left` function.
1000	#[test]
1001	fn fold_left_test() {
1002		assert_eq!(
1003			crate::classes::foldable::fold_left::<RcFnBrand, IdentityBrand, _, _>(
1004				|acc, x: i32| acc + x,
1005				0,
1006				Identity(1)
1007			),
1008			1
1009		);
1010	}
1011
1012	/// Tests the `traverse` function.
1013	#[test]
1014	fn traverse_test() {
1015		assert_eq!(
1016			crate::classes::traversable::traverse::<IdentityBrand, _, _, OptionBrand>(
1017				|x: i32| Some(x + 1),
1018				Identity(1)
1019			),
1020			Some(Identity(2))
1021		);
1022	}
1023
1024	// ParFoldable Tests
1025
1026	/// Tests `par_fold_map`.
1027	#[test]
1028	fn par_fold_map_test() {
1029		use crate::{
1030			brands::*,
1031			functions::*,
1032		};
1033
1034		let x = Identity(1);
1035		let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
1036		assert_eq!(par_fold_map::<ArcFnBrand, IdentityBrand, _, _>(f, x), "1".to_string());
1037	}
1038
1039	/// Tests `par_fold_right`.
1040	#[test]
1041	fn par_fold_right_test() {
1042		use crate::{
1043			brands::*,
1044			functions::*,
1045		};
1046
1047		let x = Identity(1);
1048		let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
1049		assert_eq!(par_fold_right::<ArcFnBrand, IdentityBrand, _, _>(f, 10, x), 11);
1050	}
1051}