|
33 | 33 | //! # let co2: I32Bool = into_coproduct(true);
|
34 | 34 | //!
|
35 | 35 | //! let folder = hlist![
|
36 |
| -//! |i| format!("i32 {}", i), |
37 |
| -//! |b| String::from(if b { "t" } else { "f" }) |
| 36 | +//! |&i| format!("i32 {}", i), |
| 37 | +//! |&b| String::from(if b { "t" } else { "f" }) |
38 | 38 | //! ];
|
39 | 39 | //!
|
40 |
| -//! assert_eq!(co1.fold(&folder), "i32 3".to_string()); |
41 |
| -//! assert_eq!(co2.fold(&folder), "t".to_string()); |
| 40 | +//! assert_eq!(co1.as_ref().fold(&folder), "i32 3".to_string()); |
| 41 | +//! assert_eq!(co2.as_ref().fold(&folder), "t".to_string()); |
| 42 | +//! |
| 43 | +//! // There is also a value consuming-variant of fold |
| 44 | +//! |
| 45 | +//! let folded = co1.fold(hlist![ |
| 46 | +//! |i| format!("i32 {}", i), |
| 47 | +//! |b| String::from(if b { "t" } else { "f" }) |
| 48 | +//! ]); |
| 49 | +//! assert_eq!(folded, "i32 3".to_string()); |
42 | 50 | //! # }
|
43 | 51 | //! ```
|
44 | 52 |
|
@@ -200,63 +208,63 @@ impl<Head, FromTail, Tail, TailIndex> CoproductSelector<FromTail, There<TailInde
|
200 | 208 | /// let co2: I32StrBool = into_coproduct(true);
|
201 | 209 | /// let co3: I32StrBool = into_coproduct(42f32);
|
202 | 210 | ///
|
203 |
| -/// let folder = hlist![|i| format!("int {}", i), |
204 |
| -/// |f| format!("float {}", f), |
205 |
| -/// |b| (if b { "t" } else { "f" }).to_string()]; |
| 211 | +/// let folder = hlist![|&i| format!("int {}", i), |
| 212 | +/// |&f| format!("float {}", f), |
| 213 | +/// |&b| (if b { "t" } else { "f" }).to_string()]; |
206 | 214 | ///
|
207 |
| -/// assert_eq!(co1.fold(&folder), "int 3".to_string()); |
208 |
| -/// assert_eq!(co2.fold(&folder), "t".to_string()); |
209 |
| -/// assert_eq!(co3.fold(&folder), "float 42".to_string()); |
| 215 | +/// assert_eq!(co1.as_ref().fold(&folder), "int 3".to_string()); |
| 216 | +/// assert_eq!(co2.as_ref().fold(&folder), "t".to_string()); |
| 217 | +/// assert_eq!(co3.as_ref().fold(&folder), "float 42".to_string()); |
210 | 218 | /// # }
|
211 | 219 | /// ```
|
212 | 220 | pub trait CoproductFoldable<Folder, Output> {
|
213 |
| - fn fold(self, f: &Folder) -> Output; |
| 221 | + fn fold(self, f: Folder) -> Output; |
214 | 222 | }
|
215 | 223 |
|
216 | 224 | impl<F, R, FTail, CH, CTail> CoproductFoldable<HCons<F, FTail>, R> for Coproduct<CH, CTail>
|
217 |
| - where F: Fn(CH) -> R, |
| 225 | + where F: FnOnce(CH) -> R, |
218 | 226 | CTail: CoproductFoldable<FTail, R>
|
219 | 227 | {
|
220 |
| - fn fold(self, f: &HCons<F, FTail>) -> R { |
| 228 | + fn fold(self, f: HCons<F, FTail>) -> R { |
221 | 229 | use self::Coproduct::*;
|
222 |
| - let ref f_head = f.head; |
223 |
| - let ref f_tail = f.tail; |
| 230 | + let f_head = f.head; |
| 231 | + let f_tail = f.tail; |
224 | 232 | match self {
|
225 | 233 | Inl(r) => (f_head)(r),
|
226 | 234 | Inr(rest) => rest.fold(f_tail),
|
227 | 235 | }
|
228 | 236 | }
|
229 | 237 | }
|
230 | 238 |
|
231 |
| -impl<'a, F, R, FTail, CH, CTail> CoproductFoldable<HCons<F, FTail>, R> for &'a Coproduct<CH, CTail> |
| 239 | +impl<'a, F, R, FTail, CH, CTail> CoproductFoldable<&'a HCons<F, FTail>, R> for &'a Coproduct<CH, CTail> |
232 | 240 | where F: Fn(&'a CH) -> R,
|
233 | 241 | CTail: 'a,
|
234 | 242 | FTail: 'a,
|
235 |
| - &'a CTail: CoproductFoldable<FTail, R> |
| 243 | + &'a CTail: CoproductFoldable<&'a FTail, R> |
236 | 244 | {
|
237 |
| - fn fold(self, f: &HCons<F, FTail>) -> R { |
| 245 | + fn fold(self, f: &'a HCons<F, FTail>) -> R { |
238 | 246 | use self::Coproduct::*;
|
239 | 247 | let ref f_head = f.head;
|
240 | 248 | let ref f_tail = f.tail;
|
241 | 249 | match *self {
|
242 | 250 | Inl(ref r) => (f_head)(r),
|
243 |
| - Inr(ref rest) => <&'a CTail as CoproductFoldable<FTail, R>>::fold(rest, f_tail), |
| 251 | + Inr(ref rest) => <&'a CTail as CoproductFoldable<&'a FTail, R>>::fold(rest, f_tail), |
244 | 252 | }
|
245 | 253 | }
|
246 | 254 | }
|
247 | 255 |
|
248 | 256 | /// This is literally impossible; CNil is not instantiable
|
249 | 257 | #[doc(hidden)]
|
250 | 258 | impl<F, R> CoproductFoldable<F, R> for CNil {
|
251 |
| - fn fold(self, _: &F) -> R { |
| 259 | + fn fold(self, _: F) -> R { |
252 | 260 | unreachable!()
|
253 | 261 | }
|
254 | 262 | }
|
255 | 263 |
|
256 | 264 | /// This is literally impossible; &CNil is not instantiable
|
257 | 265 | #[doc(hidden)]
|
258 |
| -impl<'a, F, R> CoproductFoldable<F, R> for &'a CNil { |
259 |
| - fn fold(self, _: &F) -> R { |
| 266 | +impl<'a, F, R> CoproductFoldable<&'a F, R> for &'a CNil { |
| 267 | + fn fold(self, _: &'a F) -> R { |
260 | 268 | unreachable!()
|
261 | 269 | }
|
262 | 270 | }
|
@@ -297,28 +305,27 @@ mod tests {
|
297 | 305 | type I32StrBool = Coproduct!(i32, f32, bool);
|
298 | 306 |
|
299 | 307 | let co1: I32StrBool = into_coproduct(3);
|
300 |
| - let co2: I32StrBool = into_coproduct(true); |
301 |
| - let co3: I32StrBool = into_coproduct(42f32); |
| 308 | + let folded = co1.fold(hlist![|i| format!("int {}", i), |
| 309 | + |f| format!("float {}", f), |
| 310 | + |b| (if b { "t" } else { "f" }).to_string()]); |
302 | 311 |
|
303 |
| - let folder = hlist![|i| format!("int {}", i), |
304 |
| - |f| format!("float {}", f), |
305 |
| - |b| (if b { "t" } else { "f" }).to_string()]; |
306 |
| - |
307 |
| - assert_eq!(co1.fold(&folder), "int 3".to_string()); |
308 |
| - assert_eq!(co2.fold(&folder), "t".to_string()); |
309 |
| - assert_eq!(co3.fold(&folder), "float 42".to_string()); |
| 312 | + assert_eq!(folded, "int 3".to_string()); |
310 | 313 | }
|
311 | 314 |
|
312 | 315 | #[test]
|
313 | 316 | fn test_coproduct_fold_non_consuming() {
|
314 | 317 | type I32StrBool = Coproduct!(i32, f32, bool);
|
315 | 318 |
|
316 | 319 | let co1: I32StrBool = into_coproduct(3);
|
| 320 | + let co2: I32StrBool = into_coproduct(true); |
| 321 | + let co3: I32StrBool = into_coproduct(42f32); |
317 | 322 |
|
318 | 323 | let folder = hlist![|&i| format!("int {}", i),
|
319 | 324 | |&f| format!("float {}", f),
|
320 | 325 | |&b| (if b { "t" } else { "f" }).to_string()];
|
321 | 326 |
|
322 | 327 | assert_eq!(co1.as_ref().fold(&folder), "int 3".to_string());
|
| 328 | + assert_eq!(co2.as_ref().fold(&folder), "t".to_string()); |
| 329 | + assert_eq!(co3.as_ref().fold(&folder), "float 42".to_string()); |
323 | 330 | }
|
324 | 331 | }
|
0 commit comments