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	impl Functor for IdentityBrand {
61		/// Maps a function over the value in the identity.
62		///
63		/// This method applies a function to the value inside the identity, producing a new identity with the transformed value.
64		#[document_signature]
65		///
66		#[document_type_parameters(
67			"The lifetime of the value.",
68			"The type of the value inside the identity.",
69			"The type of the result of applying the function."
70		)]
71		///
72		#[document_parameters("The function to apply.", "The identity to map over.")]
73		///
74		#[document_returns("A new identity containing the result of applying the function.")]
75		///
76		#[document_examples]
77		///
78		/// ```
79		/// use fp_library::{
80		/// 	brands::*,
81		/// 	functions::*,
82		/// 	types::*,
83		/// };
84		///
85		/// let x = Identity(5);
86		/// let y = map::<IdentityBrand, _, _>(|i| i * 2, x);
87		/// assert_eq!(y, Identity(10));
88		/// ```
89		fn map<'a, A: 'a, B: 'a>(
90			func: impl Fn(A) -> B + 'a,
91			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
92		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
93			Identity(func(fa.0))
94		}
95	}
96
97	impl Lift for IdentityBrand {
98		/// Lifts a binary function into the identity context.
99		///
100		/// This method lifts a binary function to operate on values within the identity context.
101		#[document_signature]
102		///
103		#[document_type_parameters(
104			"The lifetime of the values.",
105			"The type of the first identity's value.",
106			"The type of the second identity's value.",
107			"The return type of the function."
108		)]
109		///
110		#[document_parameters(
111			"The binary function to apply.",
112			"The first identity.",
113			"The second identity."
114		)]
115		///
116		#[document_returns("A new identity containing the result of applying the function.")]
117		#[document_examples]
118		///
119		/// ```
120		/// use fp_library::{
121		/// 	brands::*,
122		/// 	functions::*,
123		/// 	types::*,
124		/// };
125		///
126		/// let x = Identity(1);
127		/// let y = Identity(2);
128		/// let z = lift2::<IdentityBrand, _, _, _>(|a, b| a + b, x, y);
129		/// assert_eq!(z, Identity(3));
130		/// ```
131		fn lift2<'a, A, B, C>(
132			func: impl Fn(A, B) -> C + 'a,
133			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
134			fb: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>),
135		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
136		where
137			A: 'a,
138			B: 'a,
139			C: 'a, {
140			Identity(func(fa.0, fb.0))
141		}
142	}
143
144	impl Pointed for IdentityBrand {
145		/// Wraps a value in an identity.
146		///
147		/// This method wraps a value in an identity context.
148		#[document_signature]
149		///
150		#[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
151		///
152		#[document_parameters("The value to wrap.")]
153		///
154		#[document_returns("An identity containing the value.")]
155		///
156		#[document_examples]
157		///
158		/// ```
159		/// use fp_library::{
160		/// 	brands::*,
161		/// 	functions::*,
162		/// 	types::*,
163		/// };
164		///
165		/// let x = pure::<IdentityBrand, _>(5);
166		/// assert_eq!(x, Identity(5));
167		/// ```
168		fn pure<'a, A: 'a>(a: A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
169			Identity(a)
170		}
171	}
172
173	impl ApplyFirst for IdentityBrand {}
174	impl ApplySecond for IdentityBrand {}
175
176	impl Semiapplicative for IdentityBrand {
177		/// Applies a wrapped function to a wrapped value.
178		///
179		/// This method applies a function wrapped in an identity to a value wrapped in an identity.
180		#[document_signature]
181		///
182		#[document_type_parameters(
183			"The lifetime of the values.",
184			"The brand of the cloneable function wrapper.",
185			"The type of the input value.",
186			"The type of the output value."
187		)]
188		///
189		#[document_parameters(
190			"The identity containing the function.",
191			"The identity containing the value."
192		)]
193		///
194		#[document_returns("A new identity containing the result of applying the function.")]
195		#[document_examples]
196		///
197		/// ```
198		/// use fp_library::{
199		/// 	brands::*,
200		/// 	functions::*,
201		/// 	types::*,
202		/// };
203		///
204		/// let f = Identity(cloneable_fn_new::<RcFnBrand, _, _>(|x: i32| x * 2));
205		/// let x = Identity(5);
206		/// let y = apply::<RcFnBrand, IdentityBrand, _, _>(f, x);
207		/// assert_eq!(y, Identity(10));
208		/// ```
209		fn apply<'a, FnBrand: 'a + CloneableFn, A: 'a + Clone, B: 'a>(
210			ff: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, <FnBrand as CloneableFn>::Of<'a, A, B>>),
211			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
212		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
213			Identity(ff.0(fa.0))
214		}
215	}
216
217	impl Semimonad for IdentityBrand {
218		/// Chains identity computations.
219		///
220		/// This method chains two identity computations, where the second computation depends on the result of the first.
221		#[document_signature]
222		///
223		#[document_type_parameters(
224			"The lifetime of the values.",
225			"The type of the result of the first computation.",
226			"The type of the result of the second computation."
227		)]
228		///
229		#[document_parameters(
230			"The first identity.",
231			"The function to apply to the value inside the identity."
232		)]
233		///
234		#[document_returns("The result of applying `f` to the value.")]
235		#[document_examples]
236		///
237		/// ```
238		/// use fp_library::{
239		/// 	brands::*,
240		/// 	functions::*,
241		/// 	types::*,
242		/// };
243		///
244		/// let x = Identity(5);
245		/// let y = bind::<IdentityBrand, _, _>(x, |i| Identity(i * 2));
246		/// assert_eq!(y, Identity(10));
247		/// ```
248		fn bind<'a, A: 'a, B: 'a>(
249			ma: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
250			func: impl Fn(A) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
251		) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
252			func(ma.0)
253		}
254	}
255
256	impl Foldable for IdentityBrand {
257		/// Folds the identity from the right.
258		///
259		/// 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.
260		#[document_signature]
261		///
262		#[document_type_parameters(
263			"The lifetime of the values.",
264			"The brand of the cloneable function to use.",
265			"The type of the elements in the structure.",
266			"The type of the accumulator."
267		)]
268		///
269		#[document_parameters(
270			"The function to apply to each element and the accumulator.",
271			"The initial value of the accumulator.",
272			"The identity to fold."
273		)]
274		///
275		#[document_returns("The final accumulator value.")]
276		#[document_examples]
277		///
278		/// ```
279		/// use fp_library::{
280		/// 	brands::*,
281		/// 	functions::*,
282		/// 	types::*,
283		/// };
284		///
285		/// let x = Identity(5);
286		/// let y = fold_right::<RcFnBrand, IdentityBrand, _, _>(|a, b| a + b, 10, x);
287		/// assert_eq!(y, 15);
288		/// ```
289		fn fold_right<'a, FnBrand, A: 'a, B: 'a>(
290			func: impl Fn(A, B) -> B + 'a,
291			initial: B,
292			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
293		) -> B
294		where
295			FnBrand: CloneableFn + 'a, {
296			func(fa.0, initial)
297		}
298
299		/// Folds the identity from the left.
300		///
301		/// 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.
302		#[document_signature]
303		///
304		#[document_type_parameters(
305			"The lifetime of the values.",
306			"The brand of the cloneable function to use.",
307			"The type of the elements in the structure.",
308			"The type of the accumulator."
309		)]
310		///
311		#[document_parameters(
312			"The function to apply to the accumulator and each element.",
313			"The initial value of the accumulator.",
314			"The structure to fold."
315		)]
316		///
317		#[document_returns("The final accumulator value.")]
318		#[document_examples]
319		///
320		/// ```
321		/// use fp_library::{
322		/// 	brands::*,
323		/// 	functions::*,
324		/// 	types::*,
325		/// };
326		///
327		/// let x = Identity(5);
328		/// let y = fold_left::<RcFnBrand, IdentityBrand, _, _>(|b, a| b + a, 10, x);
329		/// assert_eq!(y, 15);
330		/// ```
331		fn fold_left<'a, FnBrand, A: 'a, B: 'a>(
332			func: impl Fn(B, A) -> B + 'a,
333			initial: B,
334			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
335		) -> B
336		where
337			FnBrand: CloneableFn + 'a, {
338			func(initial, fa.0)
339		}
340
341		/// Maps the value to a monoid and returns it.
342		///
343		/// This method maps the element of the identity to a monoid.
344		#[document_signature]
345		///
346		#[document_type_parameters(
347			"The lifetime of the values.",
348			"The brand of the cloneable function to use.",
349			"The type of the elements in the structure.",
350			"The type of the monoid."
351		)]
352		///
353		#[document_parameters("The mapping function.", "The identity to fold.")]
354		///
355		#[document_returns("The monoid value.")]
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 = fold_map::<RcFnBrand, IdentityBrand, _, _>(|a: i32| a.to_string(), x);
368		/// assert_eq!(y, "5".to_string());
369		/// ```
370		fn fold_map<'a, FnBrand, A: 'a, M>(
371			func: impl Fn(A) -> M + 'a,
372			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
373		) -> M
374		where
375			M: Monoid + 'a,
376			FnBrand: CloneableFn + 'a, {
377			func(fa.0)
378		}
379	}
380
381	impl Traversable for IdentityBrand {
382		/// Traverses the identity with an applicative function.
383		///
384		/// This method maps the element of the identity to a computation, evaluates it, and wraps the result in the applicative context.
385		#[document_signature]
386		///
387		#[document_type_parameters(
388			"The lifetime of the values.",
389			"The type of the elements in the traversable structure.",
390			"The type of the elements in the resulting traversable structure.",
391			"The applicative context."
392		)]
393		///
394		#[document_parameters(
395			"The function to apply to each element, returning a value in an applicative context.",
396			"The identity to traverse."
397		)]
398		///
399		#[document_returns("The identity wrapped in the applicative context.")]
400		#[document_examples]
401		///
402		/// ```
403		/// use fp_library::{
404		/// 	brands::*,
405		/// 	functions::*,
406		/// 	types::*,
407		/// };
408		///
409		/// let x = Identity(5);
410		/// let y = traverse::<IdentityBrand, _, _, OptionBrand>(|a| Some(a * 2), x);
411		/// assert_eq!(y, Some(Identity(10)));
412		/// ```
413		fn traverse<'a, A: 'a + Clone, B: 'a + Clone, F: Applicative>(
414			func: impl Fn(A) -> Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
415			ta: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
416		) -> 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>)>)
417		where
418			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>): Clone, {
419			F::map(|b| Identity(b), func(ta.0))
420		}
421
422		/// Sequences an identity of applicative.
423		///
424		/// This method evaluates the computation inside the identity and wraps the result in the applicative context.
425		#[document_signature]
426		///
427		#[document_type_parameters(
428			"The lifetime of the values.",
429			"The type of the elements in the traversable structure.",
430			"The applicative context."
431		)]
432		///
433		#[document_parameters("The identity containing the applicative value.")]
434		///
435		#[document_returns("The result of the traversal.")]
436		///
437		/// # Returns
438		///
439		/// The identity wrapped in the applicative context.
440		#[document_examples]
441		///
442		/// ```
443		/// use fp_library::{
444		/// 	brands::*,
445		/// 	functions::*,
446		/// 	types::*,
447		/// };
448		///
449		/// let x = Identity(Some(5));
450		/// let y = sequence::<IdentityBrand, _, OptionBrand>(x);
451		/// assert_eq!(y, Some(Identity(5)));
452		/// ```
453		fn sequence<'a, A: 'a + Clone, F: Applicative>(
454			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>)>)
455		) -> 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>)>)
456		where
457			Apply!(<F as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
458			Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone, {
459			F::map(|a| Identity(a), ta.0)
460		}
461	}
462
463	impl ParFoldable for IdentityBrand {
464		/// Maps the value to a monoid and returns it in parallel.
465		///
466		/// 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.
467		#[document_signature]
468		///
469		#[document_type_parameters(
470			"The lifetime of the values.",
471			"The brand of the cloneable function wrapper.",
472			"The element type.",
473			"The monoid type."
474		)]
475		///
476		#[document_parameters("The mapping function.", "The identity to fold.")]
477		///
478		#[document_returns("The combined monoid value.")]
479		///
480		#[document_examples]
481		///
482		/// ```
483		/// use fp_library::{
484		/// 	brands::*,
485		/// 	functions::*,
486		/// 	types::*,
487		/// };
488		///
489		/// let x = Identity(1);
490		/// let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
491		/// let y = par_fold_map::<ArcFnBrand, IdentityBrand, _, _>(f, x);
492		/// assert_eq!(y, "1".to_string());
493		/// ```
494		fn par_fold_map<'a, FnBrand, A, M>(
495			func: <FnBrand as SendCloneableFn>::SendOf<'a, A, M>,
496			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
497		) -> M
498		where
499			FnBrand: 'a + SendCloneableFn,
500			A: 'a + Clone + Send + Sync,
501			M: Monoid + Send + Sync + 'a, {
502			func(fa.0)
503		}
504
505		/// Folds the identity from the right in parallel.
506		///
507		/// This method performs a right-associative fold of the identity. Since `Identity` contains only one element, no actual parallelism occurs.
508		#[document_signature]
509		///
510		#[document_type_parameters(
511			"The lifetime of the values.",
512			"The brand of the cloneable function wrapper.",
513			"The element type.",
514			"The accumulator type."
515		)]
516		///
517		#[document_parameters(
518			"The thread-safe function to apply to each element and the accumulator.",
519			"The initial value of the accumulator.",
520			"The identity to fold."
521		)]
522		///
523		#[document_returns("The final accumulator value.")]
524		#[document_examples]
525		///
526		/// ```
527		/// use fp_library::{
528		/// 	brands::*,
529		/// 	functions::*,
530		/// 	types::*,
531		/// };
532		///
533		/// let x = Identity(1);
534		/// let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
535		/// let y = par_fold_right::<ArcFnBrand, IdentityBrand, _, _>(f, 10, x);
536		/// assert_eq!(y, 11);
537		/// ```
538		fn par_fold_right<'a, FnBrand, A, B>(
539			func: <FnBrand as SendCloneableFn>::SendOf<'a, (A, B), B>,
540			initial: B,
541			fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
542		) -> B
543		where
544			FnBrand: 'a + SendCloneableFn,
545			A: 'a + Clone + Send + Sync,
546			B: Send + Sync + 'a, {
547			func((fa.0, initial))
548		}
549	}
550}
551pub use inner::*;
552
553#[cfg(test)]
554mod tests {
555	use {
556		super::inner::Identity,
557		crate::{
558			brands::{
559				IdentityBrand,
560				OptionBrand,
561				RcFnBrand,
562			},
563			classes::{
564				cloneable_fn::CloneableFn,
565				functor::map,
566				pointed::pure,
567				semiapplicative::apply,
568				semimonad::bind,
569			},
570			functions::{
571				compose,
572				identity,
573			},
574		},
575		quickcheck_macros::quickcheck,
576	};
577
578	// Functor Laws
579
580	/// Tests the identity law for Functor.
581	#[quickcheck]
582	fn functor_identity(x: i32) -> bool {
583		let x = Identity(x);
584		map::<IdentityBrand, _, _>(identity, x) == x
585	}
586
587	/// Tests the composition law for Functor.
588	#[quickcheck]
589	fn functor_composition(x: i32) -> bool {
590		let x = Identity(x);
591		let f = |x: i32| x.wrapping_add(1);
592		let g = |x: i32| x.wrapping_mul(2);
593		map::<IdentityBrand, _, _>(compose(f, g), x)
594			== map::<IdentityBrand, _, _>(f, map::<IdentityBrand, _, _>(g, x))
595	}
596
597	// Applicative Laws
598
599	/// Tests the identity law for Applicative.
600	#[quickcheck]
601	fn applicative_identity(v: i32) -> bool {
602		let v = Identity(v);
603		apply::<RcFnBrand, IdentityBrand, _, _>(
604			pure::<IdentityBrand, _>(<RcFnBrand as CloneableFn>::new(identity)),
605			v,
606		) == v
607	}
608
609	/// Tests the homomorphism law for Applicative.
610	#[quickcheck]
611	fn applicative_homomorphism(x: i32) -> bool {
612		let f = |x: i32| x.wrapping_mul(2);
613		apply::<RcFnBrand, IdentityBrand, _, _>(
614			pure::<IdentityBrand, _>(<RcFnBrand as CloneableFn>::new(f)),
615			pure::<IdentityBrand, _>(x),
616		) == pure::<IdentityBrand, _>(f(x))
617	}
618
619	/// Tests the composition law for Applicative.
620	#[quickcheck]
621	fn applicative_composition(
622		w: i32,
623		u_val: i32,
624		v_val: i32,
625	) -> bool {
626		let w = Identity(w);
627		let v_fn = move |x: i32| x.wrapping_mul(v_val);
628		let u_fn = move |x: i32| x.wrapping_add(u_val);
629
630		let v = pure::<IdentityBrand, _>(<RcFnBrand as CloneableFn>::new(v_fn));
631		let u = pure::<IdentityBrand, _>(<RcFnBrand as CloneableFn>::new(u_fn));
632
633		// RHS: u <*> (v <*> w)
634		let vw = apply::<RcFnBrand, IdentityBrand, _, _>(v.clone(), w);
635		let rhs = apply::<RcFnBrand, IdentityBrand, _, _>(u.clone(), vw);
636
637		// LHS: pure(compose) <*> u <*> v <*> w
638		// equivalent to (u . v) <*> w
639		let composed = move |x| u_fn(v_fn(x));
640		let uv = pure::<IdentityBrand, _>(<RcFnBrand as CloneableFn>::new(composed));
641
642		let lhs = apply::<RcFnBrand, IdentityBrand, _, _>(uv, w);
643
644		lhs == rhs
645	}
646
647	/// Tests the interchange law for Applicative.
648	#[quickcheck]
649	fn applicative_interchange(y: i32) -> bool {
650		// u <*> pure y = pure ($ y) <*> u
651		let f = |x: i32| x.wrapping_mul(2);
652		let u = pure::<IdentityBrand, _>(<RcFnBrand as CloneableFn>::new(f));
653
654		let lhs = apply::<RcFnBrand, IdentityBrand, _, _>(u.clone(), pure::<IdentityBrand, _>(y));
655
656		let rhs_fn =
657			<RcFnBrand as CloneableFn>::new(move |f: std::rc::Rc<dyn Fn(i32) -> i32>| f(y));
658		let rhs = apply::<RcFnBrand, IdentityBrand, _, _>(pure::<IdentityBrand, _>(rhs_fn), u);
659
660		lhs == rhs
661	}
662
663	// Monad Laws
664
665	/// Tests the left identity law for Monad.
666	#[quickcheck]
667	fn monad_left_identity(a: i32) -> bool {
668		let f = |x: i32| Identity(x.wrapping_mul(2));
669		bind::<IdentityBrand, _, _>(pure::<IdentityBrand, _>(a), f) == f(a)
670	}
671
672	/// Tests the right identity law for Monad.
673	#[quickcheck]
674	fn monad_right_identity(m: i32) -> bool {
675		let m = Identity(m);
676		bind::<IdentityBrand, _, _>(m, pure::<IdentityBrand, _>) == m
677	}
678
679	/// Tests the associativity law for Monad.
680	#[quickcheck]
681	fn monad_associativity(m: i32) -> bool {
682		let m = Identity(m);
683		let f = |x: i32| Identity(x.wrapping_mul(2));
684		let g = |x: i32| Identity(x.wrapping_add(1));
685		bind::<IdentityBrand, _, _>(bind::<IdentityBrand, _, _>(m, f), g)
686			== bind::<IdentityBrand, _, _>(m, |x| bind::<IdentityBrand, _, _>(f(x), g))
687	}
688
689	// Edge Cases
690
691	/// Tests the `map` function.
692	#[test]
693	fn map_test() {
694		assert_eq!(map::<IdentityBrand, _, _>(|x: i32| x + 1, Identity(1)), Identity(2));
695	}
696
697	/// Tests the `bind` function.
698	#[test]
699	fn bind_test() {
700		assert_eq!(bind::<IdentityBrand, _, _>(Identity(1), |x| Identity(x + 1)), Identity(2));
701	}
702
703	/// Tests the `fold_right` function.
704	#[test]
705	fn fold_right_test() {
706		assert_eq!(
707			crate::classes::foldable::fold_right::<RcFnBrand, IdentityBrand, _, _>(
708				|x: i32, acc| x + acc,
709				0,
710				Identity(1)
711			),
712			1
713		);
714	}
715
716	/// Tests the `fold_left` function.
717	#[test]
718	fn fold_left_test() {
719		assert_eq!(
720			crate::classes::foldable::fold_left::<RcFnBrand, IdentityBrand, _, _>(
721				|acc, x: i32| acc + x,
722				0,
723				Identity(1)
724			),
725			1
726		);
727	}
728
729	/// Tests the `traverse` function.
730	#[test]
731	fn traverse_test() {
732		assert_eq!(
733			crate::classes::traversable::traverse::<IdentityBrand, _, _, OptionBrand>(
734				|x: i32| Some(x + 1),
735				Identity(1)
736			),
737			Some(Identity(2))
738		);
739	}
740
741	// ParFoldable Tests
742
743	/// Tests `par_fold_map`.
744	#[test]
745	fn par_fold_map_test() {
746		use crate::{
747			brands::*,
748			functions::*,
749		};
750
751		let x = Identity(1);
752		let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|x: i32| x.to_string());
753		assert_eq!(par_fold_map::<ArcFnBrand, IdentityBrand, _, _>(f, x), "1".to_string());
754	}
755
756	/// Tests `par_fold_right`.
757	#[test]
758	fn par_fold_right_test() {
759		use crate::{
760			brands::*,
761			functions::*,
762		};
763
764		let x = Identity(1);
765		let f = send_cloneable_fn_new::<ArcFnBrand, _, _>(|(a, b): (i32, i32)| a + b);
766		assert_eq!(par_fold_right::<ArcFnBrand, IdentityBrand, _, _>(f, 10, x), 11);
767	}
768}