1#[fp_macros::document_module]
23mod inner {
24 use {
25 crate::{
26 classes::{
27 send_clone_fn::SendLiftFn,
28 *,
29 },
30 kinds::*,
31 types::{
32 Dual,
33 SendEndofunction,
34 },
35 },
36 fp_macros::*,
37 };
38
39 #[kind(type Of<'a, A: 'a>: 'a;)]
53 pub trait SendRefFoldable {
54 #[document_signature]
56 #[document_type_parameters(
57 "The lifetime of the elements.",
58 "The brand of the cloneable function to use.",
59 "The type of the elements.",
60 "The monoid type."
61 )]
62 #[document_parameters(
63 "The function to map each element reference to a monoid. Must be `Send + Sync`.",
64 "The structure to fold."
65 )]
66 #[document_returns("The combined monoid value.")]
67 #[document_examples]
68 fn send_ref_fold_map<'a, FnBrand, A: Send + Sync + 'a + Clone, M>(
84 func: impl Fn(&A) -> M + Send + Sync + 'a,
85 fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
86 ) -> M
87 where
88 FnBrand: SendLiftFn + 'a,
89 M: Monoid + Send + Sync + 'a, {
90 Self::send_ref_fold_right::<FnBrand, A, M>(
91 move |a: &A, acc| Semigroup::append(func(a), acc),
92 Monoid::empty(),
93 fa,
94 )
95 }
96
97 #[document_signature]
99 #[document_type_parameters(
100 "The lifetime of the elements.",
101 "The brand of the cloneable function to use.",
102 "The type of the elements.",
103 "The type of the accumulator."
104 )]
105 #[document_parameters(
106 "The function to apply to each element reference and accumulator. Must be `Send + Sync`.",
107 "The initial value of the accumulator.",
108 "The structure to fold."
109 )]
110 #[document_returns("The final accumulator value.")]
111 #[document_examples]
112 fn send_ref_fold_right<'a, FnBrand, A: Send + Sync + 'a + Clone, B: Send + Sync + 'a>(
129 func: impl Fn(&A, B) -> B + Send + Sync + 'a,
130 initial: B,
131 fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
132 ) -> B
133 where
134 FnBrand: SendLiftFn + 'a, {
135 let f = <FnBrand as SendLiftFn>::new(move |(a, b): (A, B)| func(&a, b));
136 let m = Self::send_ref_fold_map::<FnBrand, A, SendEndofunction<FnBrand, B>>(
137 move |a: &A| {
138 let a = a.clone();
139 let f = f.clone();
140 SendEndofunction::<FnBrand, B>::new(<FnBrand as SendLiftFn>::new(move |b| {
141 let a = a.clone();
142 f((a, b))
143 }))
144 },
145 fa,
146 );
147 m.0(initial)
148 }
149
150 #[document_signature]
152 #[document_type_parameters(
153 "The lifetime of the elements.",
154 "The brand of the cloneable function to use.",
155 "The type of the elements.",
156 "The type of the accumulator."
157 )]
158 #[document_parameters(
159 "The function to apply to the accumulator and each element reference. Must be `Send + Sync`.",
160 "The initial value of the accumulator.",
161 "The structure to fold."
162 )]
163 #[document_returns("The final accumulator value.")]
164 #[document_examples]
165 fn send_ref_fold_left<'a, FnBrand, A: Send + Sync + 'a + Clone, B: Send + Sync + 'a>(
182 func: impl Fn(B, &A) -> B + Send + Sync + 'a,
183 initial: B,
184 fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
185 ) -> B
186 where
187 FnBrand: SendLiftFn + 'a, {
188 let f = <FnBrand as SendLiftFn>::new(move |(b, a): (B, A)| func(b, &a));
189 let m = Self::send_ref_fold_map::<FnBrand, A, Dual<SendEndofunction<FnBrand, B>>>(
190 move |a: &A| {
191 let a = a.clone();
192 let f = f.clone();
193 Dual(SendEndofunction::<FnBrand, B>::new(<FnBrand as SendLiftFn>::new(
194 move |b| {
195 let a = a.clone();
196 f((b, a))
197 },
198 )))
199 },
200 fa,
201 );
202 (m.0).0(initial)
203 }
204 }
205
206 #[document_signature]
210 #[document_type_parameters(
211 "The lifetime of the elements.",
212 "The brand of the cloneable function to use.",
213 "The brand of the structure.",
214 "The type of the elements.",
215 "The monoid type."
216 )]
217 #[document_parameters(
218 "The function to map each element reference to a monoid.",
219 "The structure to fold."
220 )]
221 #[document_returns("The combined monoid value.")]
222 #[document_examples]
223 pub fn send_ref_fold_map<
239 'a,
240 FnBrand: SendLiftFn + 'a,
241 Brand: SendRefFoldable,
242 A: Send + Sync + 'a + Clone,
243 M,
244 >(
245 func: impl Fn(&A) -> M + Send + Sync + 'a,
246 fa: &Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
247 ) -> M
248 where
249 M: Monoid + Send + Sync + 'a, {
250 Brand::send_ref_fold_map::<FnBrand, A, M>(func, fa)
251 }
252}
253
254pub use inner::*;