1#[fp_macros::document_module]
17mod inner {
18 use {
19 crate::{
20 classes::*,
21 kinds::*,
22 types::*,
23 },
24 fp_macros::*,
25 };
26
27 pub trait Foldable: Kind_cdc7cd43dac7585f {
41 #[document_signature]
45 #[document_type_parameters(
47 "The lifetime of the elements.",
48 "The brand of the cloneable function to use.",
49 "The type of the elements in the structure.",
50 "The type of the accumulator."
51 )]
52 #[document_parameters(
54 "The function to apply to each element and the accumulator.",
55 "The initial value of the accumulator.",
56 "The structure to fold."
57 )]
58 #[document_returns("The final accumulator value.")]
60 #[document_examples]
61 fn fold_right<'a, FnBrand, A: 'a + Clone, B: 'a>(
73 func: impl Fn(A, B) -> B + 'a,
74 initial: B,
75 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
76 ) -> B
77 where
78 FnBrand: CloneableFn + 'a, {
79 let f = <FnBrand as CloneableFn>::new(move |(a, b)| func(a, b));
80 let m = Self::fold_map::<FnBrand, A, Endofunction<FnBrand, B>>(
81 move |a: A| {
82 let f = f.clone();
83 Endofunction::<FnBrand, B>::new(<FnBrand as CloneableFn>::new(move |b| {
84 f((a.clone(), b))
85 }))
86 },
87 fa,
88 );
89 m.0(initial)
90 }
91
92 #[document_signature]
96 #[document_type_parameters(
98 "The lifetime of the elements.",
99 "The brand of the cloneable function to use.",
100 "The type of the elements in the structure.",
101 "The type of the accumulator."
102 )]
103 #[document_parameters(
105 "The function to apply to the accumulator and each element.",
106 "The initial value of the accumulator.",
107 "The structure to fold."
108 )]
109 #[document_returns("The final accumulator value.")]
111 #[document_examples]
112 fn fold_left<'a, FnBrand, A: 'a + Clone, B: 'a>(
124 func: impl Fn(B, A) -> B + 'a,
125 initial: B,
126 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
127 ) -> B
128 where
129 FnBrand: CloneableFn + 'a, {
130 let f = <FnBrand as CloneableFn>::new(move |(b, a)| func(b, a));
131 let m = Self::fold_right::<FnBrand, A, Endofunction<FnBrand, B>>(
132 move |a: A, k: Endofunction<'a, FnBrand, B>| {
133 let f = f.clone();
134 let current =
140 Endofunction::<FnBrand, B>::new(<FnBrand as CloneableFn>::new(move |b| {
141 f((b, a.clone()))
142 }));
143 Semigroup::append(k, current)
144 },
145 Endofunction::<FnBrand, B>::empty(),
146 fa,
147 );
148 m.0(initial)
149 }
150
151 #[document_signature]
155 #[document_type_parameters(
157 "The lifetime of the elements.",
158 "The brand of the cloneable function to use.",
159 "The type of the elements in the structure.",
160 "The type of the monoid."
161 )]
162 #[document_parameters(
164 "The function to map each element to a monoid.",
165 "The structure to fold."
166 )]
167 #[document_returns("The combined monoid value.")]
169 #[document_examples]
170 fn fold_map<'a, FnBrand, A: 'a + Clone, M>(
182 func: impl Fn(A) -> M + 'a,
183 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
184 ) -> M
185 where
186 M: Monoid + 'a,
187 FnBrand: CloneableFn + 'a, {
188 Self::fold_right::<FnBrand, A, M>(move |a, m| M::append(func(a), m), M::empty(), fa)
189 }
190 }
191
192 #[document_signature]
196 #[document_type_parameters(
198 "The lifetime of the elements.",
199 "The brand of the cloneable function to use.",
200 "The brand of the foldable structure.",
201 "The type of the elements in the structure.",
202 "The type of the accumulator."
203 )]
204 #[document_parameters(
206 "The function to apply to each element and the accumulator.",
207 "The initial value of the accumulator.",
208 "The structure to fold."
209 )]
210 #[document_returns("The final accumulator value.")]
212 #[document_examples]
213 pub fn fold_right<'a, FnBrand, Brand: Foldable, A: 'a + Clone, B: 'a>(
225 func: impl Fn(A, B) -> B + 'a,
226 initial: B,
227 fa: Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
228 ) -> B
229 where
230 FnBrand: CloneableFn + 'a, {
231 Brand::fold_right::<FnBrand, A, B>(func, initial, fa)
232 }
233
234 #[document_signature]
238 #[document_type_parameters(
240 "The lifetime of the elements.",
241 "The brand of the cloneable function to use.",
242 "The brand of the foldable structure.",
243 "The type of the elements in the structure.",
244 "The type of the accumulator."
245 )]
246 #[document_parameters(
248 "The function to apply to the accumulator and each element.",
249 "The initial value of the accumulator.",
250 "The structure to fold."
251 )]
252 #[document_returns("The final accumulator value.")]
254 #[document_examples]
255 pub fn fold_left<'a, FnBrand, Brand: Foldable, A: 'a + Clone, B: 'a>(
267 func: impl Fn(B, A) -> B + 'a,
268 initial: B,
269 fa: Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
270 ) -> B
271 where
272 FnBrand: CloneableFn + 'a, {
273 Brand::fold_left::<FnBrand, A, B>(func, initial, fa)
274 }
275
276 #[document_signature]
280 #[document_type_parameters(
282 "The lifetime of the elements.",
283 "The brand of the cloneable function to use.",
284 "The brand of the foldable structure.",
285 "The type of the elements in the structure.",
286 "The type of the monoid."
287 )]
288 #[document_parameters(
290 "The function to map each element to a monoid.",
291 "The structure to fold."
292 )]
293 #[document_returns("The combined monoid value.")]
295 #[document_examples]
296 pub fn fold_map<'a, FnBrand, Brand: Foldable, A: 'a + Clone, M>(
308 func: impl Fn(A) -> M + 'a,
309 fa: Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
310 ) -> M
311 where
312 M: Monoid + 'a,
313 FnBrand: CloneableFn + 'a, {
314 Brand::fold_map::<FnBrand, A, M>(func, fa)
315 }
316}
317
318pub use inner::*;