deep_causality_haft 0.4.3

HKT traits for for the deep_causality crate.
Documentation
/*
 * SPDX-License-Identifier: MIT
 * Copyright (c) 2023 - 2026. The DeepCausality Authors and Contributors. All Rights Reserved.
 */

use crate::{
    Applicative, CloneFunctor, CoMonad, DebugFunctor, EqFunctor, Foldable, Functor, HKT, Monad,
    NoConstraint, Pure, Satisfies,
};
use alloc::boxed::Box;

/// `BoxWitness` is a zero-sized type that acts as a Higher-Kinded Type (HKT) witness
/// for the `Box<T>` type constructor. It allows `Box` to be used with generic
/// functional programming traits like `Functor`, `Applicative`, `Foldable`, and `Monad`.
///
/// By implementing `HKT` for `BoxWitness`, we can write generic functions that operate
/// on any type that has the "shape" of `Box`, without knowing the inner type `T`.
///
/// # Constraint
///
/// `BoxWitness` uses `NoConstraint`, meaning it works with any type `T`.
pub struct BoxWitness;

impl HKT for BoxWitness {
    type Constraint = NoConstraint;

    /// Specifies that `BoxWitness` represents the `Box<T>` type constructor.
    type Type<T> = Box<T>;
}

// Implementation of Functor for BoxWitness
impl Functor<BoxWitness> for BoxWitness {
    /// Implements the `fmap` operation for `Box<T>`.
    ///
    /// If the `Box` contains a `value`, the function `f` is applied to `value`,
    /// and the result is wrapped in a new `Box`.
    ///
    /// # Arguments
    ///
    /// *   `m_a`: The `Box` to map over.
    /// *   `f`: The function to apply to the value inside the `Box`.
    ///
    /// # Returns
    ///
    /// A new `Box` with the function applied to its content.
    fn fmap<A, B, Func>(
        m_a: <BoxWitness as HKT>::Type<A>,
        mut f: Func,
    ) -> <BoxWitness as HKT>::Type<B>
    where
        A: Satisfies<NoConstraint>,
        B: Satisfies<NoConstraint>,
        Func: FnMut(A) -> B,
    {
        Box::new(f(*m_a))
    }
}

// Implementation of Pure for BoxWitness
impl Pure<BoxWitness> for BoxWitness {
    /// Lifts a pure value into a `Box`.
    fn pure<T>(value: T) -> <BoxWitness as HKT>::Type<T>
    where
        T: Satisfies<NoConstraint>,
    {
        Box::new(value)
    }
}

// Implementation of Applicative for BoxWitness
impl Applicative<BoxWitness> for BoxWitness {
    /// Applies a function wrapped in a `Box` (`f_ab`) to a value wrapped in a `Box` (`f_a`).
    fn apply<A, B, Func>(
        mut f_ab: <BoxWitness as HKT>::Type<Func>,
        f_a: <BoxWitness as HKT>::Type<A>,
    ) -> <BoxWitness as HKT>::Type<B>
    where
        A: Satisfies<NoConstraint> + Clone,
        B: Satisfies<NoConstraint>,
        Func: Satisfies<NoConstraint> + FnMut(A) -> B,
    {
        Box::new((*f_ab)(*f_a))
    }
}

// Implementation of Foldable for BoxWitness
impl Foldable<BoxWitness> for BoxWitness {
    /// Folds (reduces) a `Box` into a single value.
    ///
    /// The function `f` is applied with the initial accumulator and the `value` inside the `Box`.
    ///
    /// # Arguments
    ///
    /// *   `fa`: The `Box` to fold.
    /// *   `init`: The initial accumulator value.
    /// *   `f`: The folding function.
    ///
    /// # Returns
    ///
    /// The accumulated result.
    fn fold<A, B, Func>(fa: Box<A>, init: B, mut f: Func) -> B
    where
        Func: FnMut(B, A) -> B,
    {
        f(init, *fa)
    }
}

// Implementation of Monad for BoxWitness
impl Monad<BoxWitness> for BoxWitness {
    /// Implements the `bind` operation for `Box<T>`.
    fn bind<A, B, Func>(
        m_a: <BoxWitness as HKT>::Type<A>,
        mut f: Func,
    ) -> <BoxWitness as HKT>::Type<B>
    where
        A: Satisfies<NoConstraint>,
        B: Satisfies<NoConstraint>,
        Func: FnMut(A) -> <BoxWitness as HKT>::Type<B>,
    {
        f(*m_a)
    }
}

// Implementation of EqFunctor for BoxWitness (structural equality through the `Box`).
// The parameters are spelled through the HKT projection (not `&Box<T>`) to avoid
// `clippy::borrowed_box`, matching `CoMonad::extract` above.
impl EqFunctor for BoxWitness {
    fn eq_type<T: PartialEq>(a: &<Self as HKT>::Type<T>, b: &<Self as HKT>::Type<T>) -> bool {
        a == b
    }
}

// Implementation of DebugFunctor for BoxWitness (delegates to `Box`'s own `Debug`).
impl DebugFunctor for BoxWitness {
    fn fmt_type<T: core::fmt::Debug>(
        fa: &<Self as HKT>::Type<T>,
        f: &mut core::fmt::Formatter<'_>,
    ) -> core::fmt::Result {
        core::fmt::Debug::fmt(fa, f)
    }
}

// Implementation of CloneFunctor for BoxWitness (delegates to `Box`'s own `Clone`).
// The parameter is spelled through the HKT projection (not `&Box<T>`) to avoid
// `clippy::borrowed_box`, matching `EqFunctor`/`CoMonad::extract` above.
impl CloneFunctor for BoxWitness {
    fn clone_type<T: Clone>(fa: &<Self as HKT>::Type<T>) -> <Self as HKT>::Type<T> {
        fa.clone()
    }
}

// Implementation of CoMonad for BoxWitness
impl CoMonad<BoxWitness> for BoxWitness {
    fn extract<A>(fa: &<Self as HKT>::Type<A>) -> A
    where
        A: Satisfies<NoConstraint> + Clone,
    {
        *fa.clone()
    }

    fn extend<A, B, Func>(fa: &<Self as HKT>::Type<A>, mut f: Func) -> <Self as HKT>::Type<B>
    where
        A: Satisfies<NoConstraint> + Clone,
        B: Satisfies<NoConstraint>,
        Func: FnMut(&<Self as HKT>::Type<A>) -> B,
    {
        Box::new(f(fa))
    }
}