1#[fp_macros::document_module]
28mod inner {
29 use {
30 crate::{
31 classes::*,
32 kinds::*,
33 types::{
34 Dual,
35 Endofunction,
36 },
37 },
38 fp_macros::*,
39 };
40
41 #[kind(type Of<'a, A: 'a>: 'a;)]
51 pub trait RefFoldableWithIndex: RefFoldable + WithIndex {
52 #[document_signature]
55 #[document_type_parameters(
56 "The lifetime of the values.",
57 "The brand of the cloneable function to use.",
58 "The type of the elements.",
59 "The monoid type."
60 )]
61 #[document_parameters(
62 "The function to apply to each element's index and reference.",
63 "The structure to fold over."
64 )]
65 #[document_returns("The combined result.")]
66 #[document_examples]
67 fn ref_fold_map_with_index<'a, FnBrand, A: 'a + Clone, R: Monoid + 'a>(
84 f: impl Fn(Self::Index, &A) -> R + 'a,
85 fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
86 ) -> R
87 where
88 FnBrand: LiftFn + 'a,
89 Self::Index: 'a, {
90 Self::ref_fold_right_with_index::<FnBrand, A, R>(
91 move |i, a: &A, acc| Semigroup::append(f(i, a), acc),
92 Monoid::empty(),
93 fa,
94 )
95 }
96
97 #[document_signature]
99 #[document_type_parameters(
100 "The lifetime of the values.",
101 "The brand of the cloneable function to use.",
102 "The type of the elements.",
103 "The type of the accumulator."
104 )]
105 #[document_parameters(
106 "The function to apply to each element's index, reference, and accumulator.",
107 "The initial value of the accumulator.",
108 "The structure to fold over."
109 )]
110 #[document_returns("The final accumulator value.")]
111 #[document_examples]
112 fn ref_fold_right_with_index<'a, FnBrand, A: 'a + Clone, B: 'a>(
129 func: impl Fn(Self::Index, &A, B) -> B + 'a,
130 initial: B,
131 fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
132 ) -> B
133 where
134 FnBrand: LiftFn + 'a,
135 Self::Index: 'a, {
136 let f = <FnBrand as LiftFn>::new(move |(i, a, b): (Self::Index, A, B)| func(i, &a, b));
137 let m = Self::ref_fold_map_with_index::<FnBrand, A, Endofunction<FnBrand, B>>(
138 move |i, a: &A| {
139 let a = a.clone();
140 let f = f.clone();
141 Endofunction::<FnBrand, B>::new(<FnBrand as LiftFn>::new(move |b| {
142 let a = a.clone();
143 let i = i.clone();
144 f((i, a, b))
145 }))
146 },
147 fa,
148 );
149 m.0(initial)
150 }
151
152 #[document_signature]
154 #[document_type_parameters(
155 "The lifetime of the values.",
156 "The brand of the cloneable function to use.",
157 "The type of the elements.",
158 "The type of the accumulator."
159 )]
160 #[document_parameters(
161 "The function to apply to the accumulator, each element's index, and reference.",
162 "The initial value of the accumulator.",
163 "The structure to fold over."
164 )]
165 #[document_returns("The final accumulator value.")]
166 #[document_examples]
167 fn ref_fold_left_with_index<'a, FnBrand, A: 'a + Clone, B: 'a>(
184 func: impl Fn(Self::Index, B, &A) -> B + 'a,
185 initial: B,
186 fa: &Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
187 ) -> B
188 where
189 FnBrand: LiftFn + 'a,
190 Self::Index: 'a, {
191 let f = <FnBrand as LiftFn>::new(move |(i, b, a): (Self::Index, B, A)| func(i, b, &a));
192 let m = Self::ref_fold_map_with_index::<FnBrand, A, Dual<Endofunction<FnBrand, B>>>(
193 move |i, a: &A| {
194 let a = a.clone();
195 let f = f.clone();
196 Dual(Endofunction::<FnBrand, B>::new(<FnBrand as LiftFn>::new(move |b| {
197 let a = a.clone();
198 let i = i.clone();
199 f((i, b, a))
200 })))
201 },
202 fa,
203 );
204 (m.0).0(initial)
205 }
206 }
207
208 #[document_signature]
212 #[document_type_parameters(
213 "The lifetime of the values.",
214 "The brand of the cloneable function to use.",
215 "The brand of the structure.",
216 "The type of the elements.",
217 "The monoid type."
218 )]
219 #[document_parameters(
220 "The function to apply to each element's index and reference.",
221 "The structure to fold over."
222 )]
223 #[document_returns("The combined result.")]
224 #[document_examples]
225 pub fn ref_fold_map_with_index<
241 'a,
242 FnBrand: LiftFn + 'a,
243 Brand: RefFoldableWithIndex,
244 A: 'a + Clone,
245 R: Monoid + 'a,
246 >(
247 f: impl Fn(Brand::Index, &A) -> R + 'a,
248 fa: &Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
249 ) -> R
250 where
251 Brand::Index: 'a, {
252 Brand::ref_fold_map_with_index::<FnBrand, A, R>(f, fa)
253 }
254}
255
256pub use inner::*;