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}