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