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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
use Deref;
/// Type alias for a boxed, dynamically dispatched, repeatable closure.
/// `BFn<A, B>` is equivalent to `Box<dyn Fn(A) -> B + 'static>`.
/// This represents a heap-allocated closure that can be called multiple times.
type BFn<A, B> = ;
/// Type alias for a boxed, dynamically dispatched, once-callable closure.
/// `BFnOnce<A, B>` is equivalent to `Box<dyn FnOnce(A) -> B + 'static>`.
/// This represents a heap-allocated closure that can be called at most once.
type BFnOnce<A, B> = ;
/// A wrapper around `BFn<A, B>` (a `Box<dyn Fn(A) -> B + 'static>`).
///
/// This struct provides a concrete type for heap-allocated, repeatable closures,
/// which is useful for storing them in structs or passing them as arguments
/// where a concrete type is needed (e.g., in trait implementations like `Functor` for functions).
///
/// `CFn` stands for "Clonable Function" or "Composable Function", though it's not inherently `Clone`
/// unless the underlying boxed closure captures only `Clone` data (which `Box<dyn Fn>` doesn't guarantee).
/// The primary purpose here is to provide a newtype wrapper.
///
/// # Examples
/// ```
/// use monadify::function::CFn;
///
/// let add_one = CFn::new(|x: i32| x + 1);
/// assert_eq!(add_one.call(5), 6);
/// assert_eq!(add_one.call(10), 11); // Can be called multiple times
/// ```
;
/// A wrapper around `BFnOnce<A, B>` (a `Box<dyn FnOnce(A) -> B + 'static>`).
///
/// This struct provides a concrete type for heap-allocated, once-callable closures.
/// Similar to `CFn`, it's useful for type concretization.
///
/// # Examples
/// ```
/// use monadify::function::CFnOnce;
///
/// let s = "hello".to_string();
/// // This closure captures `s` by move, so it's FnOnce.
/// let append_s_once = CFnOnce::new(move |x: i32| format!("{}-{}", s, x));
/// assert_eq!(append_s_once.call_once(5), "hello-5");
/// // append_s_once.call_once(10); // This would be a compile error (use of moved value) if not for Box
/// // but logically it's consumed.
/// ```
;
/// Allows `CFn<A, B>` to be dereferenced to `&Box<dyn Fn(A) -> B + 'static>`.
/// This enables calling the boxed closure directly using `(*cfn_instance)(arg)` syntax
/// if desired, though `cfn_instance.call(arg)` is generally preferred for clarity.
/// Allows `CFnOnce<A, B>` to be dereferenced to `&Box<dyn FnOnce(A) -> B + 'static>`.
/// Composes two boxed `Fn` closures.
/// Given `f: A -> B` and `g: B -> C`, returns a new boxed closure `h: A -> C`
/// such that `h(x) = g(f(x))`.
/// Composes two boxed `FnOnce` closures.
/// Given `f: A -> B` and `g: B -> C`, returns a new boxed closure `h: A -> C`
/// such that `h(x) = g(f(x))`.
/// The resulting closure is also `FnOnce`.
/// Implements `f >> g` (forward composition) for `CFn`.
/// `(self >> rhs)(x)` is equivalent to `rhs(self(x))`.
/// `CFn<A,B> >> CFn<B,C>` results in `CFn<A,C>`.
/// Implements `g << f` (backward composition) for `CFn`.
/// `(self << rhs)(x)` is equivalent to `self(rhs(x))`.
/// `CFn<B,C> << CFn<A,B>` results in `CFn<A,C>`.
/// Implements `f >> g` (forward composition) for `CFnOnce`.
/// `(self >> rhs)(x)` is equivalent to `rhs(self(x))`.
/// `CFnOnce<A,B> >> CFnOnce<B,C>` results in `CFnOnce<A,C>`.
/// Implements `g << f` (backward composition) for `CFnOnce`.
/// `(self << rhs)(x)` is equivalent to `self(rhs(x))`.
/// `CFnOnce<B,C> << CFnOnce<A,B>` results in `CFnOnce<A,C>`.