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