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
147
148
149
150
151
152
/*
* SPDX-License-Identifier: MIT
* Copyright (c) 2023 - 2026. The DeepCausality Authors and Contributors. All Rights Reserved.
*/
use crate::;
/// The `CoMonad` trait represents a comonadic context, which is the dual of a `Monad`.
///
/// While a `Monad` allows for chaining computations that produce values *within* a context
/// (e.g., `bind` for `M<A>` to `M<B>`), a `CoMonad` focuses on computations that consume
/// values *from* a context and produce new contexts based on observations.
///
/// Think of a `CoMonad` as a context that can be "inspected" or "observed" to yield a value,
/// and then "extended" to produce new contexts by applying a function that observes the original context.
///
/// # Unified Design
///
/// This trait unifies the previous `CoMonad` and `BoundedComonad` traits into a single
/// hierarchy using the constraint system. Types that need algebraic bounds (like
/// `CausalTensor` needing `TensorData`) specify their constraint via the HKT's
/// `Constraint` associated type.
///
/// # Intuition & Analogy
///
/// A common analogy is a spreadsheet cell:
/// - `extract` gets the value of the current cell.
/// - `extend` allows you to fill a new spreadsheet with the results of formulas applied
/// to the original spreadsheet. Each cell in the new spreadsheet is derived by observing
/// the context of the old spreadsheet (e.g., the cell itself and its neighbors).
///
/// # Laws (Informal)
///
/// 1. **Left Identity**: `extend(w, extract) = w`
/// (Extending a context with its own `extract` function should yield the original context).
/// 2. **Right Identity**: `extract(extend(w, f)) = f(w)`
/// (Extracting from an extended context should be the same as directly applying the function `f` to the context).
/// 3. **Associativity**: `extend(extend(w, f), g) = extend(w, |w_prime| g(extend(w_prime, f)))`
/// (Extending twice is equivalent to extending once with a composed function).
///
/// # Type Parameters
///
/// * `F`: A Higher-Kinded Type (HKT) witness that represents the type constructor
/// (e.g., `BoxWitness`, `CausalTensorWitness`). This `F` must also be a `Functor`.