1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/*
* SPDX-License-Identifier: MIT
* Copyright (c) 2023 - 2026. The DeepCausality Authors and Contributors. All Rights Reserved.
*/
//! # The Free Monad
//!
//! `Free<F, A>` is the **free monad** on a functor `F`: the initial monad through which `F`'s
//! operations factor. It turns any [`Functor`] into a [`Monad`] and is the canonical carrier for
//! **algebraic effects with handlers** (Plotkin & Power, *Algebraic Operations and Generic
//! Effects*, 2003; Swierstra, *Data Types à la Carte*, JFP 18(4), 2008; Awodey, *Category Theory*
//! 2nd ed. §10). An *operation* lives in the functor `F`; a *program* is a tree of operations
//! terminated by pure values; a *handler* is an `F`-algebra that folds the tree into a result.
//!
//! ```text
//! Free f a = Pure a | Suspend (f (Free f a))
//! ```
//!
//! - `pure a` = `Pure a`
//! - `bind (Pure a) k` = `k a`
//! - `bind (Suspend s) k` = `Suspend (fmap (|m| bind m k) s)`
//!
//! The three monad laws hold for **every** functor `F`, using only `F`'s functor laws. This is
//! machine-checked in `lean/DeepCausalityFormal/Haft/FreeMonad.lean` and witnessed in
//! `deep_causality_haft/tests/formalization_lean/free_monad_tests.rs`.
//!
//! ## Rust encoding note (`Fn + Clone`)
//!
//! The monadic operations ([`bind`](Free::bind), [`map`](Free::map)) require the mapping function
//! to be `Fn + Clone`, not the bare `FnMut` of the [`Functor`]/[`Monad`] traits. The reason is
//! ownership: `bind` threads the continuation through **every** hole of the functor node, and a
//! multi-hole functor (e.g. a map/`Vec`) needs one copy of the continuation per hole. This is the
//! standard Rust free-monad constraint, so the monadic surface is provided as inherent methods;
//! [`FreeWitness`] implements [`HKT`] and [`Pure`] (which need no cloning).
use crate::;
use Box;
use PhantomData;
/// The free monad on a functor `F`: `Pure a | Suspend (f (Free f a))`.
///
/// `F` is an [`HKT`] witness that is a [`Functor`] over the unconstrained (`NoConstraint`)
/// universe — the functor of *operations*. `Free<F, A>` is a program tree whose leaves are pure
/// `A` values and whose branches are `F`-shaped operation nodes.
// NOTE: `Free` has no *derived* `PartialEq`/`Eq`/`Debug`/`Clone`. `#[derive]`, or any hand impl
// gated on the GAT-projection field bound `F::Type<Box<Free<F,A>>>: Trait`, makes the instance
// conditional on that projection, so discharging it at a concrete witness re-enters the trait
// solver and overflows (`error[E0275]`). Instead, opt-in `PartialEq`/`Eq`/`Debug`/`Clone` are
// provided in `free_instances.rs` for any operation functor whose witness implements
// `EqFunctor`/`DebugFunctor`/`CloneFunctor` — the recursion runs through those witness methods, not
// a projection bound, so it terminates. Programs can still be compared by folding them to a
// canonical value with `fold` (see the witness tests); the two agree.
/// The [`HKT`] witness for the free monad over the operation functor `F`.
;