@@ -43,6 +43,8 @@ much easier to implement.
43
43
#[cfg(not(stage0))] use cmp::Ord;
44
44
#[cfg(not(stage0))] use option::{Option, Some, None};
45
45
#[cfg(not(stage0))] use vec::OwnedVector;
46
+ #[cfg(not(stage0))] use num::{One, Zero};
47
+ #[cfg(not(stage0))] use ops::{Add, Mul};
46
48
47
49
#[cfg(stage0)]
48
50
pub trait Times {
@@ -212,6 +214,81 @@ pub fn min<T: Ord>(iter: &fn(f: &fn(T) -> bool) -> bool) -> Option<T> {
212
214
result
213
215
}
214
216
217
+ /**
218
+ * Reduce an iterator to an accumulated value.
219
+ *
220
+ * # Example:
221
+ *
222
+ * ~~~~
223
+ * assert_eq!(fold(0i, |f| int::range(1, 5, f), |a, x| *a += x), 10);
224
+ * ~~~~
225
+ */
226
+ #[cfg(not(stage0))]
227
+ #[inline]
228
+ pub fn fold<T, U>(start: T, iter: &fn(f: &fn(U) -> bool) -> bool, f: &fn(&mut T, U)) -> T {
229
+ let mut result = start;
230
+ for iter |x| {
231
+ f(&mut result, x);
232
+ }
233
+ result
234
+ }
235
+
236
+ /**
237
+ * Reduce an iterator to an accumulated value.
238
+ *
239
+ * `fold_ref` is usable in some generic functions where `fold` is too lenient to type-check, but it
240
+ * forces the iterator to yield borrowed pointers.
241
+ *
242
+ * # Example:
243
+ *
244
+ * ~~~~
245
+ * fn product<T: One + Mul<T, T>>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T {
246
+ * fold_ref(One::one::<T>(), iter, |a, x| *a = a.mul(x))
247
+ * }
248
+ * ~~~~
249
+ */
250
+ #[cfg(not(stage0))]
251
+ #[inline]
252
+ pub fn fold_ref<T, U>(start: T, iter: &fn(f: &fn(&U) -> bool) -> bool, f: &fn(&mut T, &U)) -> T {
253
+ let mut result = start;
254
+ for iter |x| {
255
+ f(&mut result, x);
256
+ }
257
+ result
258
+ }
259
+
260
+ /**
261
+ * Return the sum of the items yielding by an iterator.
262
+ *
263
+ * # Example:
264
+ *
265
+ * ~~~~
266
+ * let xs: ~[int] = ~[1, 2, 3, 4];
267
+ * assert_eq!(do sum |f| { xs.each(f) }, 10);
268
+ * ~~~~
269
+ */
270
+ #[cfg(not(stage0))]
271
+ #[inline(always)]
272
+ pub fn sum<T: Zero + Add<T, T>>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T {
273
+ fold_ref(Zero::zero::<T>(), iter, |a, x| *a = a.add(x))
274
+ }
275
+
276
+ /**
277
+ * Return the product of the items yielded by an iterator.
278
+ *
279
+ * # Example:
280
+ *
281
+ * ~~~~
282
+ * let xs: ~[int] = ~[1, 2, 3, 4];
283
+ * assert_eq!(do product |f| { xs.each(f) }, 24);
284
+ * ~~~~
285
+ */
286
+ #[cfg(not(stage0))]
287
+ #[inline(always)]
288
+ pub fn product<T: One + Mul<T, T>>(iter: &fn(f: &fn(&T) -> bool) -> bool) -> T {
289
+ fold_ref(One::one::<T>(), iter, |a, x| *a = a.mul(x))
290
+ }
291
+
215
292
#[cfg(test)]
216
293
mod tests {
217
294
use super::*;
@@ -254,4 +331,33 @@ mod tests {
254
331
let xs = ~[8, 2, 3, 1, -5, 9, 11, 15];
255
332
assert_eq!(min(|f| xs.each(f)).unwrap(), &-5);
256
333
}
334
+
335
+ #[test]
336
+ fn test_fold() {
337
+ assert_eq!(fold(0i, |f| int::range(1, 5, f), |a, x| *a += x), 10);
338
+ }
339
+
340
+ #[test]
341
+ fn test_sum() {
342
+ let xs: ~[int] = ~[1, 2, 3, 4];
343
+ assert_eq!(do sum |f| { xs.each(f) }, 10);
344
+ }
345
+
346
+ #[test]
347
+ fn test_empty_sum() {
348
+ let xs: ~[int] = ~[];
349
+ assert_eq!(do sum |f| { xs.each(f) }, 0);
350
+ }
351
+
352
+ #[test]
353
+ fn test_product() {
354
+ let xs: ~[int] = ~[1, 2, 3, 4];
355
+ assert_eq!(do product |f| { xs.each(f) }, 24);
356
+ }
357
+
358
+ #[test]
359
+ fn test_empty_product() {
360
+ let xs: ~[int] = ~[];
361
+ assert_eq!(do product |f| { xs.each(f) }, 1);
362
+ }
257
363
}
0 commit comments