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