1#[fp_macros::document_module]
17mod inner {
18 use {
19 crate::{
20 classes::*,
21 kinds::*,
22 types::*,
23 },
24 fp_macros::*,
25 };
26
27 #[document_examples]
46 pub trait Foldable: Kind_cdc7cd43dac7585f {
70 #[document_signature]
74 #[document_type_parameters(
76 "The lifetime of the elements.",
77 "The brand of the cloneable function to use.",
78 "The type of the elements in the structure.",
79 "The type of the accumulator."
80 )]
81 #[document_parameters(
83 "The function to apply to each element and the accumulator.",
84 "The initial value of the accumulator.",
85 "The structure to fold."
86 )]
87 #[document_returns("The final accumulator value.")]
89 #[document_examples]
90 fn fold_right<'a, FnBrand, A: 'a + Clone, B: 'a>(
102 func: impl Fn(A, B) -> B + 'a,
103 initial: B,
104 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
105 ) -> B
106 where
107 FnBrand: CloneableFn + 'a, {
108 let f = <FnBrand as CloneableFn>::new(move |(a, b)| func(a, b));
109 let m = Self::fold_map::<FnBrand, A, Endofunction<FnBrand, B>>(
110 move |a: A| {
111 let f = f.clone();
112 Endofunction::<FnBrand, B>::new(<FnBrand as CloneableFn>::new(move |b| {
113 f((a.clone(), b))
114 }))
115 },
116 fa,
117 );
118 m.0(initial)
119 }
120
121 #[document_signature]
125 #[document_type_parameters(
127 "The lifetime of the elements.",
128 "The brand of the cloneable function to use.",
129 "The type of the elements in the structure.",
130 "The type of the accumulator."
131 )]
132 #[document_parameters(
134 "The function to apply to the accumulator and each element.",
135 "The initial value of the accumulator.",
136 "The structure to fold."
137 )]
138 #[document_returns("The final accumulator value.")]
140 #[document_examples]
141 fn fold_left<'a, FnBrand, A: 'a + Clone, B: 'a>(
153 func: impl Fn(B, A) -> B + 'a,
154 initial: B,
155 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
156 ) -> B
157 where
158 FnBrand: CloneableFn + 'a, {
159 let f = <FnBrand as CloneableFn>::new(move |(b, a)| func(b, a));
160 let m = Self::fold_right::<FnBrand, A, Endofunction<FnBrand, B>>(
161 move |a: A, k: Endofunction<'a, FnBrand, B>| {
162 let f = f.clone();
163 let current =
169 Endofunction::<FnBrand, B>::new(<FnBrand as CloneableFn>::new(move |b| {
170 f((b, a.clone()))
171 }));
172 Semigroup::append(k, current)
173 },
174 Endofunction::<FnBrand, B>::empty(),
175 fa,
176 );
177 m.0(initial)
178 }
179
180 #[document_signature]
184 #[document_type_parameters(
186 "The lifetime of the elements.",
187 "The brand of the cloneable function to use.",
188 "The type of the elements in the structure.",
189 "The type of the monoid."
190 )]
191 #[document_parameters(
193 "The function to map each element to a monoid.",
194 "The structure to fold."
195 )]
196 #[document_returns("The combined monoid value.")]
198 #[document_examples]
199 fn fold_map<'a, FnBrand, A: 'a + Clone, M>(
211 func: impl Fn(A) -> M + 'a,
212 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
213 ) -> M
214 where
215 M: Monoid + 'a,
216 FnBrand: CloneableFn + 'a, {
217 Self::fold_right::<FnBrand, A, M>(move |a, m| M::append(func(a), m), M::empty(), fa)
218 }
219 }
220
221 #[document_signature]
225 #[document_type_parameters(
227 "The lifetime of the elements.",
228 "The brand of the cloneable function to use.",
229 "The brand of the foldable structure.",
230 "The type of the elements in the structure.",
231 "The type of the accumulator."
232 )]
233 #[document_parameters(
235 "The function to apply to each element and the accumulator.",
236 "The initial value of the accumulator.",
237 "The structure to fold."
238 )]
239 #[document_returns("The final accumulator value.")]
241 #[document_examples]
242 pub fn fold_right<'a, FnBrand, Brand: Foldable, A: 'a + Clone, B: 'a>(
254 func: impl Fn(A, B) -> B + 'a,
255 initial: B,
256 fa: Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
257 ) -> B
258 where
259 FnBrand: CloneableFn + 'a, {
260 Brand::fold_right::<FnBrand, A, B>(func, initial, fa)
261 }
262
263 #[document_signature]
267 #[document_type_parameters(
269 "The lifetime of the elements.",
270 "The brand of the cloneable function to use.",
271 "The brand of the foldable structure.",
272 "The type of the elements in the structure.",
273 "The type of the accumulator."
274 )]
275 #[document_parameters(
277 "The function to apply to the accumulator and each element.",
278 "The initial value of the accumulator.",
279 "The structure to fold."
280 )]
281 #[document_returns("The final accumulator value.")]
283 #[document_examples]
284 pub fn fold_left<'a, FnBrand, Brand: Foldable, A: 'a + Clone, B: 'a>(
296 func: impl Fn(B, A) -> B + 'a,
297 initial: B,
298 fa: Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
299 ) -> B
300 where
301 FnBrand: CloneableFn + 'a, {
302 Brand::fold_left::<FnBrand, A, B>(func, initial, fa)
303 }
304
305 #[document_signature]
309 #[document_type_parameters(
311 "The lifetime of the elements.",
312 "The brand of the cloneable function to use.",
313 "The brand of the foldable structure.",
314 "The type of the elements in the structure.",
315 "The type of the monoid."
316 )]
317 #[document_parameters(
319 "The function to map each element to a monoid.",
320 "The structure to fold."
321 )]
322 #[document_returns("The combined monoid value.")]
324 #[document_examples]
325 pub fn fold_map<'a, FnBrand, Brand: Foldable, A: 'a + Clone, M>(
337 func: impl Fn(A) -> M + 'a,
338 fa: Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
339 ) -> M
340 where
341 M: Monoid + 'a,
342 FnBrand: CloneableFn + 'a, {
343 Brand::fold_map::<FnBrand, A, M>(func, fa)
344 }
345}
346
347pub use inner::*;