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}