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