1#[fp_macros::document_module]
6mod inner {
7 use {
8 crate::{
9 Apply,
10 brands::optics::*,
11 classes::{
12 UnsizedCoercible,
13 monoid::Monoid,
14 optics::*,
15 },
16 kinds::*,
17 types::optics::Forget,
18 },
19 fp_macros::*,
20 std::marker::PhantomData,
21 };
22
23 pub use crate::classes::optics::fold::FoldFunc;
24
25 #[document_type_parameters("The type of the inner function.")]
32 pub struct IterableFoldFn<F>(pub F);
33
34 #[document_type_parameters("The type of the inner function.")]
35 #[document_parameters("The fold instance.")]
36 impl<F: Clone> Clone for IterableFoldFn<F> {
37 #[document_signature]
38 #[document_returns("A new `Fold` instance that is a copy of the original.")]
39 #[document_examples]
40 fn clone(&self) -> Self {
49 IterableFoldFn(self.0.clone())
50 }
51 }
52
53 #[document_type_parameters(
54 "The lifetime of the function.",
55 "The source type of the structure.",
56 "The type of the focuses.",
57 "The iterable type returned by the function.",
58 "The type of the inner function."
59 )]
60 #[document_parameters("The fold instance.")]
61 impl<'a, S, A, I, F> FoldFunc<'a, S, A> for IterableFoldFn<F>
62 where
63 F: Fn(S) -> I,
64 I: IntoIterator<Item = A>,
65 {
66 #[document_signature]
67 #[document_type_parameters("The monoid type to fold into.")]
68 #[document_parameters("The mapping function.", "The structure to fold.")]
69 #[document_returns("The combined monoid value.")]
70 #[document_examples]
71 fn apply<R: Monoid>(
87 &self,
88 f: impl Fn(A) -> R + 'a,
89 s: S,
90 ) -> R {
91 (self.0)(s).into_iter().fold(R::empty(), |r, a| R::append(r, f(a)))
92 }
93 }
94
95 #[document_type_parameters(
99 "The lifetime of the values.",
100 "The reference-counted pointer type.",
101 "The source type of the structure.",
102 "The target type of the structure.",
103 "The source type of the focus.",
104 "The target type of the focus.",
105 "The type of the fold function."
106 )]
107 pub struct Fold<'a, PointerBrand, S, T, A, B, F>
108 where
109 PointerBrand: UnsizedCoercible,
110 F: FoldFunc<'a, S, A>,
111 S: 'a,
112 T: 'a,
113 A: 'a,
114 B: 'a, {
115 pub fold_fn: F,
117 pub(crate) _phantom: PhantomData<(&'a (S, T, A, B), PointerBrand)>,
118 }
119
120 #[document_type_parameters(
121 "The lifetime of the values.",
122 "The reference-counted pointer type.",
123 "The source type of the structure.",
124 "The target type of the structure.",
125 "The source type of the focus.",
126 "The target type of the focus.",
127 "The type of the fold function."
128 )]
129 #[document_parameters("The fold instance.")]
130 impl<'a, PointerBrand, S, T, A, B, F> Clone for Fold<'a, PointerBrand, S, T, A, B, F>
131 where
132 PointerBrand: UnsizedCoercible,
133 F: FoldFunc<'a, S, A> + Clone,
134 S: 'a,
135 T: 'a,
136 A: 'a,
137 B: 'a,
138 {
139 #[document_signature]
140 #[document_returns("A new `Fold` instance that is a copy of the original.")]
141 #[document_examples]
142 fn clone(&self) -> Self {
161 Fold {
162 fold_fn: self.fold_fn.clone(),
163 _phantom: PhantomData,
164 }
165 }
166 }
167
168 #[document_type_parameters(
169 "The lifetime of the values.",
170 "The reference-counted pointer type.",
171 "The source type of the structure.",
172 "The target type of the structure.",
173 "The source type of the focus.",
174 "The target type of the focus.",
175 "The type of the fold function."
176 )]
177 #[document_parameters("The fold instance.")]
178 impl<'a, PointerBrand, S, T, A, B, F> Fold<'a, PointerBrand, S, T, A, B, F>
179 where
180 PointerBrand: UnsizedCoercible,
181 F: FoldFunc<'a, S, A>,
182 S: 'a,
183 T: 'a,
184 A: 'a,
185 B: 'a,
186 {
187 #[document_signature]
189 #[document_parameters("The fold function.")]
191 #[document_returns("A new instance of the type.")]
193 #[document_examples]
195 pub fn new(fold_fn: F) -> Self {
213 Fold {
214 fold_fn,
215 _phantom: PhantomData,
216 }
217 }
218
219 #[document_signature]
221 #[document_parameters("The structure to fold.")]
223 #[document_returns("A `Vec` containing all the focuses.")]
225 #[document_examples]
227 pub fn to_vec(
245 &self,
246 s: S,
247 ) -> Vec<A>
248 where
249 A: Clone, {
250 self.fold_fn.apply::<Vec<A>>(|a| vec![a], s)
251 }
252 }
253
254 #[document_type_parameters(
255 "The lifetime of the values.",
256 "The reference-counted pointer type.",
257 "The source type of the structure.",
258 "The target type of the structure.",
259 "The source type of the focus.",
260 "The target type of the focus.",
261 "The type of the fold function."
262 )]
263 #[document_parameters("The fold instance.")]
264 impl<'a, PointerBrand, S, T, A, B, F> FoldOptic<'a, S, A> for Fold<'a, PointerBrand, S, T, A, B, F>
265 where
266 PointerBrand: UnsizedCoercible,
267 F: FoldFunc<'a, S, A> + Clone + 'a,
268 S: 'a,
269 T: 'a,
270 A: 'a,
271 B: 'a,
272 {
273 #[document_signature]
274 #[document_type_parameters(
275 "The monoid type.",
276 "The reference-counted pointer type for the Forget brand."
277 )]
278 #[document_parameters("The profunctor value to transform.")]
279 #[document_returns("The transformed profunctor value.")]
280 #[document_examples]
281 fn evaluate<R: 'a + Monoid + 'static, Q: UnsizedCoercible + 'static>(
300 &self,
301 pab: Apply!(<ForgetBrand<Q, R> as Kind!( type Of<'b, X: 'b, Y: 'b>: 'b; )>::Of<'a, A, A>),
302 ) -> Apply!(<ForgetBrand<Q, R> as Kind!( type Of<'b, X: 'b, Y: 'b>: 'b; )>::Of<'a, S, S>)
303 {
304 let fold_fn = self.fold_fn.clone();
305 Forget::<Q, R, S, S>::new(move |s: S| {
306 let pab_fn = pab.0.clone();
307 fold_fn.apply::<R>(move |a| (pab_fn)(a), s)
308 })
309 }
310 }
311
312 #[document_type_parameters(
316 "The lifetime of the values.",
317 "The reference-counted pointer type.",
318 "The type of the structure.",
319 "The type of the focus.",
320 "The type of the fold function."
321 )]
322 pub struct FoldPrime<'a, PointerBrand, S, A, F>
323 where
324 PointerBrand: UnsizedCoercible,
325 F: FoldFunc<'a, S, A>,
326 S: 'a,
327 A: 'a, {
328 pub fold_fn: F,
330 pub(crate) _phantom: PhantomData<(&'a (S, A), PointerBrand)>,
331 }
332
333 #[document_type_parameters(
334 "The lifetime of the values.",
335 "The reference-counted pointer type.",
336 "The type of the structure.",
337 "The type of the focus.",
338 "The type of the fold function."
339 )]
340 #[document_parameters("The fold instance.")]
341 impl<'a, PointerBrand, S, A, F> Clone for FoldPrime<'a, PointerBrand, S, A, F>
342 where
343 PointerBrand: UnsizedCoercible,
344 F: FoldFunc<'a, S, A> + Clone,
345 S: 'a,
346 A: 'a,
347 {
348 #[document_signature]
349 #[document_returns("A new `FoldPrime` instance that is a copy of the original.")]
350 #[document_examples]
351 fn clone(&self) -> Self {
368 FoldPrime {
369 fold_fn: self.fold_fn.clone(),
370 _phantom: PhantomData,
371 }
372 }
373 }
374
375 #[document_type_parameters(
376 "The lifetime of the values.",
377 "The reference-counted pointer type.",
378 "The type of the structure.",
379 "The type of the focus.",
380 "The type of the fold function."
381 )]
382 #[document_parameters("The fold instance.")]
383 impl<'a, PointerBrand, S, A, F> FoldPrime<'a, PointerBrand, S, A, F>
384 where
385 PointerBrand: UnsizedCoercible,
386 F: FoldFunc<'a, S, A>,
387 S: 'a,
388 A: 'a,
389 {
390 #[document_signature]
392 #[document_parameters("The fold function.")]
394 #[document_returns("A new instance of the type.")]
396 #[document_examples]
398 pub fn new(fold_fn: F) -> Self {
415 FoldPrime {
416 fold_fn,
417 _phantom: PhantomData,
418 }
419 }
420
421 #[document_signature]
423 #[document_parameters("The structure to fold.")]
425 #[document_returns("A `Vec` containing all the focuses.")]
427 #[document_examples]
429 pub fn to_vec(
446 &self,
447 s: S,
448 ) -> Vec<A>
449 where
450 A: Clone, {
451 self.fold_fn.apply::<Vec<A>>(|a| vec![a], s)
452 }
453 }
454
455 #[document_type_parameters(
456 "The lifetime of the values.",
457 "The reference-counted pointer type.",
458 "The type of the structure.",
459 "The type of the focus.",
460 "The type of the fold function."
461 )]
462 #[document_parameters("The fold instance.")]
463 impl<'a, PointerBrand, S, A, F> FoldOptic<'a, S, A> for FoldPrime<'a, PointerBrand, S, A, F>
464 where
465 PointerBrand: UnsizedCoercible,
466 F: FoldFunc<'a, S, A> + Clone + 'a,
467 S: 'a,
468 A: 'a,
469 {
470 #[document_signature]
471 #[document_type_parameters(
472 "The monoid type.",
473 "The reference-counted pointer type for the Forget brand."
474 )]
475 #[document_parameters("The profunctor value to transform.")]
476 #[document_returns("The transformed profunctor value.")]
477 #[document_examples]
478 fn evaluate<R: 'a + Monoid + 'static, Q: UnsizedCoercible + 'static>(
497 &self,
498 pab: Apply!(<ForgetBrand<Q, R> as Kind!( type Of<'b, X: 'b, Y: 'b>: 'b; )>::Of<'a, A, A>),
499 ) -> Apply!(<ForgetBrand<Q, R> as Kind!( type Of<'b, X: 'b, Y: 'b>: 'b; )>::Of<'a, S, S>)
500 {
501 let fold_fn = self.fold_fn.clone();
502 Forget::<Q, R, S, S>::new(move |s: S| {
503 let pab_fn = pab.0.clone();
504 fold_fn.apply::<R>(move |a| (pab_fn)(a), s)
505 })
506 }
507 }
508}
509pub use inner::*;