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 #[kind(type Of<'a, A: 'a>: 'a;)]
70 pub trait Foldable {
71 #[document_signature]
75 #[document_type_parameters(
77 "The lifetime of the elements.",
78 "The brand of the cloneable function to use.",
79 "The type of the elements in the structure.",
80 "The type of the accumulator."
81 )]
82 #[document_parameters(
84 "The function to apply to each element and the accumulator.",
85 "The initial value of the accumulator.",
86 "The structure to fold."
87 )]
88 #[document_returns("The final accumulator value.")]
90 #[document_examples]
91 fn fold_right<'a, FnBrand, A: 'a + Clone, B: 'a>(
103 func: impl Fn(A, B) -> B + 'a,
104 initial: B,
105 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
106 ) -> B
107 where
108 FnBrand: CloneableFn + 'a, {
109 let f = <FnBrand as CloneableFn>::new(move |(a, b)| func(a, b));
110 let m = Self::fold_map::<FnBrand, A, Endofunction<FnBrand, B>>(
111 move |a: A| {
112 let f = f.clone();
113 Endofunction::<FnBrand, B>::new(<FnBrand as CloneableFn>::new(move |b| {
114 f((a.clone(), b))
115 }))
116 },
117 fa,
118 );
119 m.0(initial)
120 }
121
122 #[document_signature]
126 #[document_type_parameters(
128 "The lifetime of the elements.",
129 "The brand of the cloneable function to use.",
130 "The type of the elements in the structure.",
131 "The type of the accumulator."
132 )]
133 #[document_parameters(
135 "The function to apply to the accumulator and each element.",
136 "The initial value of the accumulator.",
137 "The structure to fold."
138 )]
139 #[document_returns("The final accumulator value.")]
141 #[document_examples]
142 fn fold_left<'a, FnBrand, A: 'a + Clone, B: 'a>(
154 func: impl Fn(B, A) -> B + 'a,
155 initial: B,
156 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
157 ) -> B
158 where
159 FnBrand: CloneableFn + 'a, {
160 let f = <FnBrand as CloneableFn>::new(move |(b, a)| func(b, a));
161 let m = Self::fold_right::<FnBrand, A, Endofunction<FnBrand, B>>(
162 move |a: A, k: Endofunction<'a, FnBrand, B>| {
163 let f = f.clone();
164 let current =
170 Endofunction::<FnBrand, B>::new(<FnBrand as CloneableFn>::new(move |b| {
171 f((b, a.clone()))
172 }));
173 Semigroup::append(k, current)
174 },
175 Endofunction::<FnBrand, B>::empty(),
176 fa,
177 );
178 m.0(initial)
179 }
180
181 #[document_signature]
185 #[document_type_parameters(
187 "The lifetime of the elements.",
188 "The brand of the cloneable function to use.",
189 "The type of the elements in the structure.",
190 "The type of the monoid."
191 )]
192 #[document_parameters(
194 "The function to map each element to a monoid.",
195 "The structure to fold."
196 )]
197 #[document_returns("The combined monoid value.")]
199 #[document_examples]
200 fn fold_map<'a, FnBrand, A: 'a + Clone, M>(
212 func: impl Fn(A) -> M + 'a,
213 fa: Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
214 ) -> M
215 where
216 M: Monoid + 'a,
217 FnBrand: CloneableFn + 'a, {
218 Self::fold_right::<FnBrand, A, M>(move |a, m| M::append(func(a), m), M::empty(), fa)
219 }
220 }
221
222 #[document_signature]
226 #[document_type_parameters(
228 "The lifetime of the elements.",
229 "The brand of the cloneable function to use.",
230 "The brand of the foldable structure.",
231 "The type of the elements in the structure.",
232 "The type of the accumulator."
233 )]
234 #[document_parameters(
236 "The function to apply to each element and the accumulator.",
237 "The initial value of the accumulator.",
238 "The structure to fold."
239 )]
240 #[document_returns("The final accumulator value.")]
242 #[document_examples]
243 pub fn fold_right<'a, FnBrand, Brand: Foldable, A: 'a + Clone, B: 'a>(
255 func: impl Fn(A, B) -> B + 'a,
256 initial: B,
257 fa: Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
258 ) -> B
259 where
260 FnBrand: CloneableFn + 'a, {
261 Brand::fold_right::<FnBrand, A, B>(func, initial, fa)
262 }
263
264 #[document_signature]
268 #[document_type_parameters(
270 "The lifetime of the elements.",
271 "The brand of the cloneable function to use.",
272 "The brand of the foldable structure.",
273 "The type of the elements in the structure.",
274 "The type of the accumulator."
275 )]
276 #[document_parameters(
278 "The function to apply to the accumulator and each element.",
279 "The initial value of the accumulator.",
280 "The structure to fold."
281 )]
282 #[document_returns("The final accumulator value.")]
284 #[document_examples]
285 pub fn fold_left<'a, FnBrand, Brand: Foldable, A: 'a + Clone, B: 'a>(
297 func: impl Fn(B, A) -> B + 'a,
298 initial: B,
299 fa: Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
300 ) -> B
301 where
302 FnBrand: CloneableFn + 'a, {
303 Brand::fold_left::<FnBrand, A, B>(func, initial, fa)
304 }
305
306 #[document_signature]
310 #[document_type_parameters(
312 "The lifetime of the elements.",
313 "The brand of the cloneable function to use.",
314 "The brand of the foldable structure.",
315 "The type of the elements in the structure.",
316 "The type of the monoid."
317 )]
318 #[document_parameters(
320 "The function to map each element to a monoid.",
321 "The structure to fold."
322 )]
323 #[document_returns("The combined monoid value.")]
325 #[document_examples]
326 pub fn fold_map<'a, FnBrand, Brand: Foldable, A: 'a + Clone, M>(
338 func: impl Fn(A) -> M + 'a,
339 fa: Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
340 ) -> M
341 where
342 M: Monoid + 'a,
343 FnBrand: CloneableFn + 'a, {
344 Brand::fold_map::<FnBrand, A, M>(func, fa)
345 }
346}
347
348pub use inner::*;