fp_library/types/
send_endofunction.rs1#[fp_macros::document_module]
6mod inner {
7 use {
8 crate::{
9 classes::{
10 send_clone_fn::SendLiftFn,
11 *,
12 },
13 functions::identity,
14 },
15 fp_macros::*,
16 std::fmt::{
17 self,
18 Debug,
19 Formatter,
20 },
21 };
22
23 #[document_type_parameters(
34 "The lifetime of the function and its captured data.",
35 "The brand of the thread-safe cloneable function wrapper.",
36 "The input and output type of the function."
37 )]
38 pub struct SendEndofunction<'a, FnBrand: SendLiftFn, A: 'a>(
40 pub <FnBrand as SendCloneFn>::Of<'a, A, A>,
42 );
43
44 #[document_type_parameters(
45 "The lifetime of the function and its captured data.",
46 "The brand of the function (e.g., `ArcFnBrand`).",
47 "The input and output type of the function."
48 )]
49 impl<'a, FnBrand: SendLiftFn, A: 'a> SendEndofunction<'a, FnBrand, A> {
50 #[document_signature]
52 #[document_parameters("The function to wrap.")]
54 #[document_returns("A new `SendEndofunction`.")]
56 #[document_examples]
58 pub fn new(f: <FnBrand as SendCloneFn>::Of<'a, A, A>) -> Self {
73 Self(f)
74 }
75 }
76
77 #[document_type_parameters(
78 "The lifetime of the function and its captured data.",
79 "The brand of the function (e.g., `ArcFnBrand`).",
80 "The input and output type of the function."
81 )]
82 #[document_parameters("The function to clone.")]
83 impl<'a, FnBrand: SendLiftFn, A: 'a> Clone for SendEndofunction<'a, FnBrand, A> {
84 #[document_signature]
85 #[document_returns("The cloned endofunction.")]
86 #[document_examples]
87 fn clone(&self) -> Self {
102 Self::new(self.0.clone())
103 }
104 }
105
106 #[document_type_parameters(
107 "The lifetime of the function and its captured data.",
108 "The brand of the function (e.g., `ArcFnBrand`).",
109 "The input and output type of the function."
110 )]
111 #[document_parameters("The function to format.")]
112 impl<'a, FnBrand: SendLiftFn, A: 'a> Debug for SendEndofunction<'a, FnBrand, A>
113 where
114 <FnBrand as SendCloneFn>::Of<'a, A, A>: Debug,
115 {
116 #[document_signature]
117 #[document_parameters("The formatter to use.")]
118 #[document_returns("The result of the formatting operation.")]
119 #[document_examples]
120 fn fmt(
134 &self,
135 fmt: &mut Formatter<'_>,
136 ) -> fmt::Result {
137 fmt.debug_tuple("SendEndofunction").field(&self.0).finish()
138 }
139 }
140
141 #[document_type_parameters(
142 "The lifetime of the function and its captured data.",
143 "The brand of the function (e.g., `ArcFnBrand`).",
144 "The input and output type of the function."
145 )]
146 impl<'a, FnBrand: 'a + SendLiftFn, A: 'a + Send + Sync> Semigroup
147 for SendEndofunction<'a, FnBrand, A>
148 {
149 #[document_signature]
153 #[document_parameters(
155 "The second function to apply (the outer function).",
156 "The first function to apply (the inner function)."
157 )]
158 #[document_returns("The composed function `a . b`.")]
160 #[document_examples]
161 fn append(
183 a: Self,
184 b: Self,
185 ) -> Self {
186 let f = a.0;
187 let g = b.0;
188 Self::new(<FnBrand as SendLiftFn>::new(move |x| f(g(x))))
189 }
190 }
191
192 #[document_type_parameters(
193 "The lifetime of the function and its captured data.",
194 "The brand of the function (e.g., `ArcFnBrand`).",
195 "The input and output type of the function."
196 )]
197 impl<'a, FnBrand: 'a + SendLiftFn, A: 'a + Send + Sync> Monoid
198 for SendEndofunction<'a, FnBrand, A>
199 {
200 #[document_signature]
202 #[document_returns("The identity endofunction.")]
204 #[document_examples]
206 fn empty() -> Self {
218 Self::new(<FnBrand as SendLiftFn>::new(identity))
219 }
220 }
221}
222pub use inner::*;
223
224#[cfg(test)]
225mod tests {
226 use {
227 super::*,
228 crate::{
229 brands::ArcFnBrand,
230 classes::send_clone_fn::SendLiftFn,
231 functions::*,
232 },
233 quickcheck_macros::quickcheck,
234 };
235
236 #[quickcheck]
237 fn semigroup_associativity(val: i32) -> bool {
238 let f =
239 SendEndofunction::<ArcFnBrand, _>::new(<ArcFnBrand as SendLiftFn>::new(|x: i32| {
240 x.wrapping_add(1)
241 }));
242 let g =
243 SendEndofunction::<ArcFnBrand, _>::new(<ArcFnBrand as SendLiftFn>::new(|x: i32| {
244 x.wrapping_mul(2)
245 }));
246 let h =
247 SendEndofunction::<ArcFnBrand, _>::new(<ArcFnBrand as SendLiftFn>::new(|x: i32| {
248 x.wrapping_sub(3)
249 }));
250
251 let lhs = append(f.clone(), append(g.clone(), h.clone()));
252 let rhs = append(append(f, g), h);
253
254 lhs.0(val) == rhs.0(val)
255 }
256
257 #[quickcheck]
258 fn monoid_left_identity(val: i32) -> bool {
259 let f =
260 SendEndofunction::<ArcFnBrand, _>::new(<ArcFnBrand as SendLiftFn>::new(|x: i32| {
261 x.wrapping_add(1)
262 }));
263 let id = empty::<SendEndofunction<ArcFnBrand, i32>>();
264
265 let res = append(id, f.clone());
266 res.0(val) == f.0(val)
267 }
268
269 #[quickcheck]
270 fn monoid_right_identity(val: i32) -> bool {
271 let f =
272 SendEndofunction::<ArcFnBrand, _>::new(<ArcFnBrand as SendLiftFn>::new(|x: i32| {
273 x.wrapping_add(1)
274 }));
275 let id = empty::<SendEndofunction<ArcFnBrand, i32>>();
276
277 let res = append(f.clone(), id);
278 res.0(val) == f.0(val)
279 }
280}