fp_library/types/
string.rs

1//! Implementations for [`String`].
2
3use crate::{
4	classes::{monoid::Monoid, semigroup::Semigroup},
5	impl_kind,
6	kinds::*,
7};
8
9impl_kind! {
10	for String {
11		type Of<'a> = String;
12	}
13}
14
15impl Semigroup for String {
16	/// Appends one string to another.
17	///
18	/// # Type Signature
19	///
20	/// `forall. Semigroup String => (String, String) -> String`
21	///
22	/// # Parameters
23	///
24	/// * `a`: The first string.
25	/// * `b`: The second string.
26	///
27	/// # Returns
28	///
29	/// The concatenated string.
30	///
31	/// # Examples
32	///
33	/// ```
34	/// use fp_library::classes::semigroup::append;
35	///
36	/// assert_eq!(append("Hello, ".to_string(), "World!".to_string()), "Hello, World!".to_string());
37	/// ```
38	fn append(
39		a: Self,
40		b: Self,
41	) -> Self {
42		a + &b
43	}
44}
45
46impl Monoid for String {
47	/// Returns an empty string.
48	///
49	/// # Type Signature
50	///
51	/// `forall. Monoid String => () -> String`
52	///
53	/// # Returns
54	///
55	/// An empty string.
56	///
57	/// # Examples
58	///
59	/// ```
60	/// use fp_library::classes::monoid::empty;
61	///
62	/// assert_eq!(empty::<String>(), "".to_string());
63	/// ```
64	fn empty() -> Self {
65		String::new()
66	}
67}
68
69#[cfg(test)]
70mod tests {
71	use crate::classes::{monoid::Monoid, semigroup::append};
72	use quickcheck_macros::quickcheck;
73
74	// Semigroup Laws
75
76	/// Tests the associativity law for Semigroup.
77	#[quickcheck]
78	fn semigroup_associativity(
79		a: String,
80		b: String,
81		c: String,
82	) -> bool {
83		append(a.clone(), append(b.clone(), c.clone())) == append(append(a, b), c)
84	}
85
86	// Monoid Laws
87
88	/// Tests the left identity law for Monoid.
89	#[quickcheck]
90	fn monoid_left_identity(a: String) -> bool {
91		append(String::empty(), a.clone()) == a
92	}
93
94	/// Tests the right identity law for Monoid.
95	#[quickcheck]
96	fn monoid_right_identity(a: String) -> bool {
97		append(a.clone(), String::empty()) == a
98	}
99}