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
14#[fp_macros::document_module]
15mod inner {
16 use fp_macros::*;
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)`.
21 #[document_examples]
22 ///
23 /// Associativity for [`String`]:
24 ///
25 /// ```
26 /// use fp_library::functions::*;
27 ///
28 /// let a = "hello".to_string();
29 /// let b = " ".to_string();
30 /// let c = "world".to_string();
31 ///
32 /// // Associativity: append(a, append(b, c)) = append(append(a, b), c)
33 /// assert_eq!(append(a.clone(), append(b.clone(), c.clone())), append(append(a, b), c),);
34 /// ```
35 ///
36 /// Associativity for [`Vec`]:
37 ///
38 /// ```
39 /// use fp_library::functions::*;
40 ///
41 /// let a = vec![1, 2];
42 /// let b = vec![3];
43 /// let c = vec![4, 5];
44 ///
45 /// assert_eq!(append(a.clone(), append(b.clone(), c.clone())), append(append(a, b), c),);
46 /// ```
47 pub trait Semigroup {
48 /// The result of combining the two values using the semigroup operation.
49 ///
50 /// This method combines two values of the same type into a single value of that type.
51 #[document_signature]
52 ///
53 #[document_parameters("The first value.", "The second value.")]
54 ///
55 #[document_returns("The combined value.")]
56 #[document_examples]
57 ///
58 /// ```
59 /// use fp_library::functions::*;
60 ///
61 /// let x = "Hello, ".to_string();
62 /// let y = "World!".to_string();
63 /// let z = append::<_>(x, y);
64 /// assert_eq!(z, "Hello, World!".to_string());
65 /// ```
66 fn append(
67 a: Self,
68 b: Self,
69 ) -> Self;
70 }
71
72 /// The result of combining the two values using the semigroup operation.
73 ///
74 /// Free function version that dispatches to [the type class' associated function][`Semigroup::append`].
75 #[document_signature]
76 ///
77 #[document_type_parameters("The type of the semigroup.")]
78 ///
79 #[document_parameters("The first value.", "The second value.")]
80 ///
81 #[document_returns("The combined value.")]
82 #[document_examples]
83 ///
84 /// ```
85 /// use fp_library::functions::*;
86 ///
87 /// let x = "Hello, ".to_string();
88 /// let y = "World!".to_string();
89 /// let z = append::<_>(x, y);
90 /// assert_eq!(z, "Hello, World!".to_string());
91 /// ```
92 pub fn append<S: Semigroup>(
93 a: S,
94 b: S,
95 ) -> S {
96 S::append(a, b)
97 }
98}
99
100pub use inner::*;