Skip to content

Commit 81ac089

Browse files
Merge pull request #360 from marvin-hansen/main
Added documentation to HAFT crate
2 parents da03a2b + daeb8e5 commit 81ac089

File tree

16 files changed

+996
-83
lines changed

16 files changed

+996
-83
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ make example
166166
* `deep_causality_algorithms`: Provides algorithms for the DeepCausality library.
167167
* `deep_causality_data_structures`: Provides data structures for the DeepCausality library.
168168
* `deep_causality_discovery`: A custom DSL for causal discovery.
169+
* `deep_causality_haft`: Higher-Order Abstract Functional Traits a.k.a HKT.
169170
* `deep_causality_macros`: Provides macros for the DeepCausality library (_deprecated_).
170171
* `deep_causality_num`: Numerical traits and utils used across the other crates.
171172
* `deep_causality_rand`: Random number generator and statistical distributions used in deep_causality_tensor and other

deep_causality_haft/BUILD.bazel

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,3 @@ rust_doc_test(
2929
tags = ["doc-test"],
3030
visibility = ["//visibility:public"],
3131
)
32-
33-
rust_test(
34-
name = "tests",
35-
srcs = glob(["tests/**"]),
36-
crate = ":deep_causality_haft",
37-
)

deep_causality_haft/src/applicative.rs

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,66 @@
44
*/
55
use crate::{Functor, HKT};
66

7-
/// Applicative: Abstracts over the ability to apply a function wrapped in a context
8-
/// to a value wrapped in a context.
7+
/// The `Applicative` trait extends `Functor` by providing methods to apply a function
8+
/// wrapped in a context to a value wrapped in a context, and to lift a pure value
9+
/// into the minimal context.
910
///
10-
/// Generic over the HKT witness `F`.
11+
/// This trait is generic over `F`, which is a Higher-Kinded Type (HKT) witness.
12+
///
13+
/// # Laws (Informal)
14+
///
15+
/// 1. **Identity**: `pure(id).apply(v) == v`
16+
/// 2. **Homomorphism**: `pure(f).apply(pure(x)) == pure(f(x))`
17+
/// 3. **Interchange**: `u.apply(pure(y)) == pure(|f| f(y)).apply(u)`
18+
///
19+
/// # Type Parameters
20+
///
21+
/// * `F`: A Higher-Kinded Type (HKT) witness that represents the type constructor
22+
/// (e.g., `OptionWitness`, `ResultWitness<E>`).
1123
pub trait Applicative<F: HKT>: Functor<F> {
12-
/// Lifts a pure value into the minimal applicative context.
24+
/// Lifts a pure value into the minimal applicative context `F::Type<T>`.
25+
///
26+
/// This is often used to introduce a value into an effectful computation
27+
/// without any side effects.
28+
///
29+
/// # Arguments
30+
///
31+
/// * `value`: The pure value to lift.
32+
///
33+
/// # Returns
34+
///
35+
/// An instance of `F::Type<T>` containing the `value`.
36+
///
37+
/// # Examples
38+
///
39+
///
1340
fn pure<T>(value: T) -> F::Type<T>;
1441

15-
/// Applies a function wrapped in a context to a value wrapped in a context.
42+
/// Applies a function wrapped in a context (`f_ab`) to a value wrapped in a context (`f_a`).
43+
///
44+
/// This allows sequencing computations where both the function and its argument
45+
/// are within the same applicative context.
46+
///
47+
/// # Arguments
48+
///
49+
/// * `f_ab`: An instance of `F::Type<Func>` containing the function to apply.
50+
/// * `f_a`: An instance of `F::Type<A>` containing the argument for the function.
51+
///
52+
/// # Returns
53+
///
54+
/// An instance of `F::Type<B>` containing the result of the application,
55+
/// or an appropriate error/empty context if either `f_ab` or `f_a` is in an
56+
/// error/empty state.
57+
///
58+
/// # Type Parameters
59+
///
60+
/// * `A`: The input type of the function.
61+
/// * `B`: The output type of the function.
62+
/// * `Func`: The type of the function, which must be `FnMut(A) -> B`.
63+
///
64+
/// # Examples
65+
///
66+
///
1667
fn apply<A, B, Func>(f_ab: F::Type<Func>, f_a: F::Type<A>) -> F::Type<B>
1768
where
1869
Func: FnMut(A) -> B,

deep_causality_haft/src/effect.rs

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,36 +12,47 @@ use crate::{HKT, HKT3, HKT4, HKT5};
1212
/// Effect3: The Bridge Trait for Arity 3 Type Constructors.
1313
///
1414
/// This trait is implemented by a user-defined **System Witness** (e.g., `MyEffect`)
15-
/// to partially apply (fix) two of the three generic parameters of the HKT3 type.
15+
/// to partially apply (fix) two of the three generic parameters of an `HKT3` type.
16+
/// It serves as a crucial component in building type-encoded effect systems,
17+
/// allowing for the explicit tracking and handling of two fixed effect types
18+
/// (e.g., Error and Warning) while keeping the primary value type generic.
1619
pub trait Effect3 {
17-
/// The fixed type for the first parameter (e.g., the Error type E).
20+
/// The fixed type for the first parameter of the `HKT3` type.
21+
/// In many effect systems, this represents the Error type (e.g., `String`, `MyErrorStruct`).
1822
type Fixed1;
1923

20-
/// The fixed type for the second parameter (e.g., the Warning/Log type W).
24+
/// The fixed type for the second parameter of the `HKT3` type.
25+
/// This often represents a Warning or Log type (e.g., `String`, `Vec<String>`).
2126
type Fixed2;
2227

23-
/// The concrete witness type that implements HKT3 with the two fixed types.
24-
/// It MUST implement HKT so we can pass it to Functor/Monad functions.
28+
/// The concrete witness type that implements `HKT3` with the two fixed types (`Fixed1`, `Fixed2`).
29+
/// This witness type *MUST* also implement `HKT` to be compatible with `Functor` and `Monad` traits.
30+
/// It acts as a token to refer to the partially applied type constructor.
2531
type HktWitness: HKT3<Self::Fixed1, Self::Fixed2> + HKT;
2632
}
2733

2834
// ----------------------------------------------------
2935
// Effect Traits (Arity 4)
3036
// ----------------------------------------------------
3137

32-
/// Effect4: The Bridge Trait for Arity 4 Type Constructors.I
38+
/// Effect4: The Bridge Trait for Arity 4 Type Constructors.
39+
///
40+
/// Similar to `Effect3`, this trait is implemented by a user-defined **System Witness**
41+
/// to partially apply (fix) three of the four generic parameters of an `HKT4` type.
42+
/// It is used for effect systems that need to track three distinct fixed effect types
43+
/// (e.g., Error, Warning, and a Counter) alongside the primary value type.
3344
pub trait Effect4 {
34-
/// The fixed type for the first parameter.
45+
/// The fixed type for the first parameter of the `HKT4` type (e.g., an Error type).
3546
type Fixed1;
3647

37-
/// The fixed type for the second parameter.
48+
/// The fixed type for the second parameter of the `HKT4` type (e.g., a Log type).
3849
type Fixed2;
3950

40-
/// The fixed type for the third parameter.
51+
/// The fixed type for the third parameter of the `HKT4` type (e.g., a Counter type).
4152
type Fixed3;
4253

43-
/// The concrete witness type that implements HKT4 with the three fixed types.
44-
/// It MUST implement HKT so we can pass it to Functor/Monad functions.
54+
/// The concrete witness type that implements `HKT4` with the three fixed types (`Fixed1`, `Fixed2`, `Fixed3`).
55+
/// This witness type *MUST* also implement `HKT` to be compatible with `Functor` and `Monad` traits.
4556
type HktWitness: HKT4<Self::Fixed1, Self::Fixed2, Self::Fixed3> + HKT;
4657
}
4758

@@ -50,12 +61,25 @@ pub trait Effect4 {
5061
// ----------------------------------------------------
5162

5263
/// Effect5: The Bridge Trait for Arity 5 Type Constructors.
64+
///
65+
/// This trait is implemented by a user-defined **System Witness**
66+
/// to partially apply (fix) four of the five generic parameters of an `HKT5` type.
67+
/// It is designed for highly expressive effect systems that need to track four distinct fixed effect types
68+
/// (e.g., Error, Warning, Counter, and Trace information) alongside the primary value type.
5369
pub trait Effect5 {
70+
/// The fixed type for the first parameter of the `HKT5` type (e.g., an Error type).
5471
type Fixed1;
72+
73+
/// The fixed type for the second parameter of the `HKT5` type (e.g., a Log type).
5574
type Fixed2;
75+
76+
/// The fixed type for the third parameter of the `HKT5` type (e.g., a Counter type).
5677
type Fixed3;
78+
79+
/// The fixed type for the fourth parameter of the `HKT5` type (e.g., a Trace type).
5780
type Fixed4;
5881

59-
/// The concrete witness type that implements HKT5 with the four fixed types.
82+
/// The concrete witness type that implements `HKT5` with the four fixed types (`Fixed1`, `Fixed2`, `Fixed3`, `Fixed4`).
83+
/// This witness type *MUST* also implement `HKT` to be compatible with `Functor` and `Monad` traits.
6084
type HktWitness: HKT5<Self::Fixed1, Self::Fixed2, Self::Fixed3, Self::Fixed4> + HKT;
6185
}

deep_causality_haft/src/extensions/hkt_option_ext.rs

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,34 @@
55

66
use crate::{Applicative, Foldable, Functor, HKT, Monad};
77

8-
// Witness for Option
8+
/// `OptionWitness` is a zero-sized type that acts as a Higher-Kinded Type (HKT) witness
9+
/// for the `Option<T>` type constructor. It allows `Option` to be used with generic
10+
/// functional programming traits like `Functor`, `Applicative`, `Foldable`, and `Monad`.
11+
///
12+
/// By implementing `HKT` for `OptionWitness`, we can write generic functions that operate
13+
/// on any type that has the "shape" of `Option`, without knowing the inner type `T`.
914
pub struct OptionWitness;
1015

1116
impl HKT for OptionWitness {
17+
/// Specifies that `OptionWitness` represents the `Option<T>` type constructor.
1218
type Type<T> = Option<T>;
1319
}
1420

1521
// Implementation of Functor for OptionWitness
1622
impl Functor<OptionWitness> for OptionWitness {
23+
/// Implements the `fmap` operation for `Option<T>`.
24+
///
25+
/// If the `Option` is `Some(value)`, the function `f` is applied to `value`,
26+
/// and the result is wrapped in `Some`. If the `Option` is `None`, `None` is returned.
27+
///
28+
/// # Arguments
29+
///
30+
/// * `m_a`: The `Option` to map over.
31+
/// * `f`: The function to apply to the value inside the `Option`.
32+
///
33+
/// # Returns
34+
///
35+
/// A new `Option` with the function applied to its content, or `None`.
1736
fn fmap<A, B, Func>(
1837
m_a: <OptionWitness as HKT>::Type<A>,
1938
f: Func,
@@ -27,10 +46,32 @@ impl Functor<OptionWitness> for OptionWitness {
2746

2847
// Implementation of Applicative for OptionWitness
2948
impl Applicative<OptionWitness> for OptionWitness {
49+
/// Lifts a pure value into a `Some` variant of `Option`.
50+
///
51+
/// # Arguments
52+
///
53+
/// * `value`: The value to wrap in `Some`.
54+
///
55+
/// # Returns
56+
///
57+
/// `Some(value)`.
3058
fn pure<T>(value: T) -> <OptionWitness as HKT>::Type<T> {
3159
Some(value)
3260
}
3361

62+
/// Applies a function wrapped in an `Option` (`f_ab`) to a value wrapped in an `Option` (`f_a`).
63+
///
64+
/// If both `f_ab` and `f_a` are `Some`, the function is applied to the value.
65+
/// If either is `None`, `None` is returned.
66+
///
67+
/// # Arguments
68+
///
69+
/// * `f_ab`: An `Option` containing the function.
70+
/// * `f_a`: An `Option` containing the argument.
71+
///
72+
/// # Returns
73+
///
74+
/// An `Option` containing the result of the application, or `None`.
3475
fn apply<A, B, Func>(
3576
f_ab: <OptionWitness as HKT>::Type<Func>,
3677
f_a: <OptionWitness as HKT>::Type<A>,
@@ -44,6 +85,21 @@ impl Applicative<OptionWitness> for OptionWitness {
4485

4586
// Implementation of Foldable for OptionWitness
4687
impl Foldable<OptionWitness> for OptionWitness {
88+
/// Folds (reduces) an `Option` into a single value.
89+
///
90+
/// If the `Option` is `Some(value)`, the function `f` is applied with the initial
91+
/// accumulator and the `value`. If the `Option` is `None`, the initial accumulator
92+
/// is returned.
93+
///
94+
/// # Arguments
95+
///
96+
/// * `fa`: The `Option` to fold.
97+
/// * `init`: The initial accumulator value.
98+
/// * `f`: The folding function.
99+
///
100+
/// # Returns
101+
///
102+
/// The accumulated result.
47103
fn fold<A, B, Func>(fa: Option<A>, init: B, mut f: Func) -> B
48104
where
49105
Func: FnMut(B, A) -> B,
@@ -57,6 +113,20 @@ impl Foldable<OptionWitness> for OptionWitness {
57113

58114
// Implementation of Monad for OptionWitness
59115
impl Monad<OptionWitness> for OptionWitness {
116+
/// Implements the `bind` (or `and_then`) operation for `Option<T>`.
117+
///
118+
/// If the `Option` is `Some(value)`, the function `f` is applied to `value`,
119+
/// which itself returns an `Option`. If the `Option` is `None`, `None` is returned.
120+
/// This effectively chains computations that might fail.
121+
///
122+
/// # Arguments
123+
///
124+
/// * `m_a`: The initial `Option`.
125+
/// * `f`: A function that takes the inner value of `m_a` and returns a new `Option`.
126+
///
127+
/// # Returns
128+
///
129+
/// A new `Option` representing the chained computation.
60130
fn bind<A, B, Func>(
61131
m_a: <OptionWitness as HKT>::Type<A>,
62132
f: Func,

0 commit comments

Comments
 (0)