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