1#[fp_macros::document_module]
4mod inner {
5 use {
6 crate::{
7 classes::*,
8 types::Endofunction,
9 },
10 fp_macros::*,
11 };
12
13 #[document_examples]
24 pub trait FoldableWithIndex: Foldable + WithIndex {
45 #[document_signature]
50 #[document_type_parameters(
51 "The lifetime of the values.",
52 "The brand of the cloneable function to use.",
53 "The type of the elements.",
54 "The monoid type."
55 )]
56 #[document_parameters(
57 "The function to apply to each element and its index.",
58 "The structure to fold over."
59 )]
60 #[document_returns("The combined result.")]
61 #[document_examples]
62 fn fold_map_with_index<'a, FnBrand, A: 'a + Clone, R: Monoid + 'a>(
76 f: impl Fn(Self::Index, A) -> R + 'a,
77 fa: Self::Of<'a, A>,
78 ) -> R
79 where
80 FnBrand: LiftFn + 'a,
81 Self::Index: 'a, {
82 Self::fold_right_with_index::<FnBrand, A, R>(
83 move |i, a, acc| Semigroup::append(f(i, a), acc),
84 Monoid::empty(),
85 fa,
86 )
87 }
88
89 #[document_signature]
93 #[document_type_parameters(
94 "The lifetime of the values.",
95 "The brand of the cloneable function to use.",
96 "The type of the elements.",
97 "The type of the accumulator."
98 )]
99 #[document_parameters(
100 "The function to apply to each element's index, the element, and the accumulator.",
101 "The initial accumulator value.",
102 "The structure to fold over."
103 )]
104 #[document_returns("The final accumulator value.")]
105 #[document_examples]
106 fn fold_right_with_index<'a, FnBrand, A: 'a + Clone, B: 'a>(
121 func: impl Fn(Self::Index, A, B) -> B + 'a,
122 initial: B,
123 fa: Self::Of<'a, A>,
124 ) -> B
125 where
126 FnBrand: LiftFn + 'a,
127 Self::Index: 'a, {
128 let f = <FnBrand as LiftFn>::new(move |(i, a, b): (Self::Index, A, B)| func(i, a, b));
129 let m = Self::fold_map_with_index::<FnBrand, A, Endofunction<FnBrand, B>>(
130 move |i: Self::Index, a: A| {
131 let f = f.clone();
132 Endofunction::<FnBrand, B>::new(<FnBrand as LiftFn>::new(move |b| {
133 f((i.clone(), a.clone(), b))
134 }))
135 },
136 fa,
137 );
138 m.0(initial)
139 }
140
141 #[document_signature]
145 #[document_type_parameters(
146 "The lifetime of the values.",
147 "The brand of the cloneable function to use.",
148 "The type of the elements.",
149 "The type of the accumulator."
150 )]
151 #[document_parameters(
152 "The function to apply to the index, the accumulator, and each element.",
153 "The initial accumulator value.",
154 "The structure to fold over."
155 )]
156 #[document_returns("The final accumulator value.")]
157 #[document_examples]
158 fn fold_left_with_index<'a, FnBrand, A: 'a + Clone, B: 'a>(
173 func: impl Fn(Self::Index, B, A) -> B + 'a,
174 initial: B,
175 fa: Self::Of<'a, A>,
176 ) -> B
177 where
178 FnBrand: LiftFn + 'a,
179 Self::Index: 'a, {
180 let f = <FnBrand as LiftFn>::new(move |(i, b, a): (Self::Index, B, A)| func(i, b, a));
181 let m = Self::fold_map_with_index::<
182 FnBrand,
183 A,
184 crate::types::Dual<Endofunction<FnBrand, B>>,
185 >(
186 move |i: Self::Index, a: A| {
187 let f = f.clone();
188 crate::types::Dual(Endofunction::<FnBrand, B>::new(<FnBrand as LiftFn>::new(
189 move |b| f((i.clone(), b, a.clone())),
190 )))
191 },
192 fa,
193 );
194 m.0.0(initial)
195 }
196 }
197
198 #[document_signature]
202 #[document_type_parameters(
203 "The lifetime of the values.",
204 "The brand of the cloneable function to use.",
205 "The brand of the structure.",
206 "The type of the elements.",
207 "The monoid type."
208 )]
209 #[document_parameters(
210 "The function to apply to each element and its index.",
211 "The structure to fold over."
212 )]
213 #[document_returns("The combined result.")]
214 #[document_examples]
215 pub fn fold_map_with_index<
229 'a,
230 FnBrand: LiftFn + 'a,
231 Brand: FoldableWithIndex,
232 A: 'a + Clone,
233 R: Monoid + 'a,
234 >(
235 f: impl Fn(Brand::Index, A) -> R + 'a,
236 fa: Brand::Of<'a, A>,
237 ) -> R
238 where
239 Brand::Index: 'a, {
240 Brand::fold_map_with_index::<FnBrand, A, R>(f, fa)
241 }
242
243 #[document_signature]
247 #[document_type_parameters(
248 "The lifetime of the values.",
249 "The brand of the cloneable function to use.",
250 "The brand of the structure.",
251 "The type of the elements.",
252 "The type of the accumulator."
253 )]
254 #[document_parameters(
255 "The function to apply.",
256 "The initial accumulator value.",
257 "The structure to fold over."
258 )]
259 #[document_returns("The final accumulator value.")]
260 #[document_examples]
261 pub fn fold_right_with_index<
276 'a,
277 FnBrand: LiftFn + 'a,
278 Brand: FoldableWithIndex,
279 A: 'a + Clone,
280 B: 'a,
281 >(
282 func: impl Fn(Brand::Index, A, B) -> B + 'a,
283 initial: B,
284 fa: Brand::Of<'a, A>,
285 ) -> B
286 where
287 Brand::Index: 'a, {
288 Brand::fold_right_with_index::<FnBrand, A, B>(func, initial, fa)
289 }
290
291 #[document_signature]
295 #[document_type_parameters(
296 "The lifetime of the values.",
297 "The brand of the cloneable function to use.",
298 "The brand of the structure.",
299 "The type of the elements.",
300 "The type of the accumulator."
301 )]
302 #[document_parameters(
303 "The function to apply.",
304 "The initial accumulator value.",
305 "The structure to fold over."
306 )]
307 #[document_returns("The final accumulator value.")]
308 #[document_examples]
309 pub fn fold_left_with_index<
324 'a,
325 FnBrand: LiftFn + 'a,
326 Brand: FoldableWithIndex,
327 A: 'a + Clone,
328 B: 'a,
329 >(
330 func: impl Fn(Brand::Index, B, A) -> B + 'a,
331 initial: B,
332 fa: Brand::Of<'a, A>,
333 ) -> B
334 where
335 Brand::Index: 'a, {
336 Brand::fold_left_with_index::<FnBrand, A, B>(func, initial, fa)
337 }
338}
339
340pub use inner::*;