Skip to main content

fp_library/types/
string.rs

1//! [`Semigroup`](crate::classes::Semigroup) and [`Monoid`](crate::classes::Monoid) instances for the standard library [`String`] type.
2//!
3//! Provides string concatenation as a monoidal operation with the empty string as the identity element.
4
5#[fp_macros::document_module]
6mod inner {
7	use {
8		crate::{
9			classes::{
10				Monoid,
11				Semigroup,
12			},
13			impl_kind,
14			kinds::*,
15		},
16		fp_macros::*,
17	};
18
19	impl_kind! {
20		for String {
21			type Of<'a> = String;
22		}
23	}
24
25	impl Semigroup for String {
26		/// The result of combining two strings.
27		///
28		/// This method combines two strings into a single string.
29		#[document_signature]
30		///
31		#[document_parameters("The first string.", "The second string.")]
32		///
33		#[document_returns("The combined string.")]
34		///
35		#[document_examples]
36		///
37		/// ```
38		/// use fp_library::functions::*;
39		///
40		/// let s1 = "Hello, ".to_string();
41		/// let s2 = "World!".to_string();
42		/// let result = append::<_>(s1, s2);
43		/// assert_eq!(result, "Hello, World!");
44		/// ```
45		fn append(
46			a: Self,
47			b: Self,
48		) -> Self {
49			a + &b
50		}
51	}
52
53	impl Monoid for String {
54		/// The identity element.
55		///
56		/// This method returns the identity element of the monoid.
57		#[document_signature]
58		///
59		#[document_returns("The identity element.")]
60		///
61		#[document_examples]
62		///
63		/// ```
64		/// use fp_library::functions::*;
65		///
66		/// let empty_string = empty::<String>();
67		/// assert_eq!(empty_string, "");
68		/// ```
69		fn empty() -> Self {
70			String::new()
71		}
72	}
73}
74
75#[cfg(test)]
76mod tests {
77	use {
78		crate::classes::{
79			monoid::Monoid,
80			semigroup::append,
81		},
82		quickcheck_macros::quickcheck,
83	};
84
85	// Semigroup Laws
86
87	/// Tests the associativity law for Semigroup.
88	#[quickcheck]
89	fn semigroup_associativity(
90		a: String,
91		b: String,
92		c: String,
93	) -> bool {
94		append(a.clone(), append(b.clone(), c.clone())) == append(append(a, b), c)
95	}
96
97	// Monoid Laws
98
99	/// Tests the left identity law for Monoid.
100	#[quickcheck]
101	fn monoid_left_identity(a: String) -> bool {
102		append(String::empty(), a.clone()) == a
103	}
104
105	/// Tests the right identity law for Monoid.
106	#[quickcheck]
107	fn monoid_right_identity(a: String) -> bool {
108		append(a.clone(), String::empty()) == a
109	}
110}