Skip to main content

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::*;