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