Skip to main content

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}