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