deep_causality_haft/monad.rs
1/*
2 * SPDX-License-Identifier: MIT
3 * Copyright (c) "2025" . The DeepCausality Authors and Contributors. All Rights Reserved.
4 */
5use crate::{Applicative, HKT};
6
7/// The `Monad` trait extends `Applicative` by providing a `bind` operation
8/// for sequencing computations that produce effectful values.
9///
10/// Monads are fundamental for managing side-effects and controlling the flow
11/// of computations in a functional style, allowing for powerful abstractions
12/// like error handling, logging, and state management.
13///
14/// This trait is generic over `F`, which is a Higher-Kinded Type (HKT) witness.
15///
16/// # Laws (Informal)
17///
18/// 1. **Left Identity**: `pure(a).bind(f) == f(a)`
19/// 2. **Right Identity**: `m.bind(pure) == m`
20/// 3. **Associativity**: `m.bind(|x| f(x).bind(g)) == m.bind(f).bind(g)`
21///
22/// # Type Parameters
23///
24/// * `F`: A Higher-Kinded Type (HKT) witness that represents the type constructor
25/// (e.g., `OptionWitness`, `ResultWitness<E>`, `VecWitness`).
26pub trait Monad<F: HKT>: Applicative<F> {
27 /// Chains a computation from an effectful value, flattening the result.
28 /// This is the core sequencing operation of a Monad.
29 ///
30 /// The `bind` method takes an effectful value (`m_a`) and a function `f`.
31 /// The function `f` takes the inner value of `m_a` and returns a new effectful value.
32 /// `bind` then flattens this nested structure into a single effectful value.
33 ///
34 /// # Arguments
35 ///
36 /// * `m_a`: The initial effectful value (`F::Type<A>`).
37 /// * `f`: A function that takes the inner value of `m_a` and returns a new effectful value (`F::Type<B>`).
38 ///
39 /// # Returns
40 ///
41 /// A new effectful value (`F::Type<B>`) representing the chained and flattened computation.
42 ///
43 /// # Type Parameters
44 ///
45 /// * `A`: The type of the value inside the initial effectful context.
46 /// * `B`: The type of the value inside the resulting effectful context.
47 /// * `Func`: The type of the binding function, which must be `FnMut(A) -> F::Type<B>`.
48 ///
49 /// # Examples
50 ///
51 /// ```
52 /// use deep_causality_haft::{Monad, OptionWitness, HKT};
53 ///
54 /// let opt_a: Option<<OptionWitness as HKT>::Type<i32>> = Some(Some(5));
55 /// let f = |x| Some(x * 2);
56 /// let opt_b = OptionWitness::bind(opt_a.unwrap(), f);
57 /// assert_eq!(opt_b, Some(10));
58 ///
59 /// let opt_none: Option<<OptionWitness as HKT>::Type<i32>> = Some(None);
60 /// let opt_none_bound = OptionWitness::bind(opt_none.unwrap(), f);
61 /// assert_eq!(opt_none_bound, None);
62 /// ```
63 fn bind<A, B, Func>(m_a: F::Type<A>, f: Func) -> F::Type<B>
64 where
65 // The function must return a new effectful type (F::Type<B>)
66 Func: FnMut(A) -> F::Type<B>;
67}