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}