fp_library/classes/
monoid.rs

1use crate::{
2	classes::{Semigroup, semigroup::Semigroup1L0T},
3	hkt::Apply1L0T,
4};
5
6/// A type class for monoids.
7///
8/// `Monoid` extends [`Semigroup`] with an identity element. A monoid is a set
9/// equipped with an associative binary operation and an identity element.
10///
11/// In functional programming, monoids are useful for combining values in
12/// a consistent way, especially when accumulating results or folding
13/// collections.
14///
15/// # Laws
16///
17/// `Monoid` instances must satisfy the following laws:
18/// * Left identity: `append(empty(), x) = x`.
19/// * Right identity: `append(x, empty()) = x`.
20/// * Associativity: `append(append(x, y), z) = append(x, append(y, z))`.
21pub trait Monoid<'a>: Semigroup<'a> {
22	/// Returns the identity element for the monoid.
23	///
24	/// # Type Signature
25	///
26	/// `Monoid a => () -> a`
27	///
28	/// # Returns
29	///
30	/// The identity element which, when combined with any other element
31	/// using the semigroup operation, leaves the other element unchanged.
32	fn empty() -> Self;
33}
34
35/// A higher-kinded Monoid, abstracting over the lifetime parameter.
36pub trait Monoid1L0T: Semigroup1L0T
37where
38	for<'a> Apply1L0T<'a, Self>: Monoid<'a>,
39{
40}
41
42/// Returns the identity element for the monoid.
43///
44/// Free function version that dispatches to [the type class' associated function][`Monoid::empty`].
45///
46/// # Type Signature
47///
48/// `Monoid a => () -> a`
49///
50/// # Returns
51///
52/// The identity element which, when combined with any other element
53/// using the semigroup operation, leaves the other element unchanged.
54///
55/// # Examples
56///
57/// ```
58/// use fp_library::functions::empty;
59///
60/// assert_eq!(empty::<String>(), "".to_string());
61///
62pub fn empty<'a, Brand: Monoid1L0T>() -> Apply1L0T<'a, Brand>
63where
64	for<'b> Apply1L0T<'b, Brand>: Monoid<'b>,
65{
66	<Apply1L0T<'a, Brand> as Monoid<'a>>::empty()
67}