fp_library/classes/semigroup.rs
1//! Semigroup type class.
2//!
3//! This module defines the [`Semigroup`] trait, which represents types that support an associative binary operation.
4
5/// A type class for types that support an associative binary operation.
6///
7/// `Semigroup` instances must satisfy the associative law:
8/// * Associativity: `append(a, append(b, c)) = append(append(a, b), c)`.
9pub trait Semigroup {
10 /// The result of combining the two values using the semigroup operation.
11 ///
12 /// This method combines two values of the same type into a single value of that type.
13 ///
14 /// ### Type Signature
15 ///
16 /// `forall a. Semigroup a => (a, a) -> a`
17 ///
18 /// ### Parameters
19 ///
20 /// * `a`: The first value.
21 /// * `b`: The second value.
22 ///
23 /// ### Returns
24 ///
25 /// The combined value.
26 ///
27 /// ### Examples
28 ///
29 /// ```
30 /// use fp_library::classes::semigroup::Semigroup;
31 /// use fp_library::types::string; // Import Semigroup impl for String
32 ///
33 /// let x = "Hello, ".to_string();
34 /// let y = "World!".to_string();
35 /// let z = String::append(x, y);
36 /// assert_eq!(z, "Hello, World!".to_string());
37 /// ```
38 fn append(
39 a: Self,
40 b: Self,
41 ) -> Self;
42}
43
44/// The result of combining the two values using the semigroup operation.
45///
46/// Free function version that dispatches to [the type class' associated function][`Semigroup::append`].
47///
48/// ### Type Signature
49///
50/// `forall a. Semigroup a => (a, a) -> a`
51///
52/// ### Type Parameters
53///
54/// * `S`: The type of the semigroup.
55///
56/// ### Parameters
57///
58/// * `a`: The first value.
59/// * `b`: The second value.
60///
61/// ### Returns
62///
63/// The combined value.
64///
65/// ### Examples
66///
67/// ```
68/// use fp_library::classes::semigroup::append;
69/// use fp_library::types::string; // Import Semigroup impl for String
70///
71/// let x = "Hello, ".to_string();
72/// let y = "World!".to_string();
73/// let z = append(x, y);
74/// assert_eq!(z, "Hello, World!".to_string());
75/// ```
76pub fn append<S: Semigroup>(
77 a: S,
78 b: S,
79) -> S {
80 S::append(a, b)
81}