//
// $Id$
//
// samskivert library - useful routines for java programs
// Copyright (C) 2001-2010 Michael Bayne, et al.
// 
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

package com.samskivert.util;

import java.math.BigInteger;
import java.util.Collection;
import java.util.Map;

/**
 * Various useful folds over iterables.
 */
public class Folds
{
    /**
     * Sums the supplied collection of numbers to an int with a left to right fold.
     */
    public static int sum (int zero, Iterable<? extends Number> values)
    {
        for (Number value : values) {
            zero += value.intValue();
        }
        return zero;
    }

    /**
     * Sums the supplied collection of numbers to a long with a left to right fold.
     */
    public static long sum (long zero, Iterable<? extends Number> values)
    {
        for (Number value : values) {
            zero += value.longValue();
        }
        return zero;
    }

    /**
     * Sums the supplied collection of numbers to a float with a left to right fold.
     */
    public static float sum (float zero, Iterable<? extends Number> values)
    {
        for (Number value : values) {
            zero += value.floatValue();
        }
        return zero;
    }

    /**
     * Sums the supplied collection of numbers to a double with a left to right fold.
     */
    public static double sum (double zero, Iterable<? extends Number> values)
    {
        for (Number value : values) {
            zero += value.doubleValue();
        }
        return zero;
    }

    /**
     * Sums the supplied collection of numbers to a bigint with a left to right fold.
     */
    public static BigInteger sum (BigInteger zero, Iterable<? extends BigInteger> values)
    {
        for (BigInteger value : values) {
            zero = zero.add(value);
        }
        return zero;
    }

    /**
     * Merges the supplied collections into <code>zero</code> using a left to right fold of
     * {@link Collection#addAll}.
     */
    public static <T, C extends Collection<T>> C addAll (
        C zero, Iterable<Collection<? extends T>> values)
    {
        for (Collection<? extends T> value : values) {
            zero.addAll(value);
        }
        return zero;
    }

    /**
     * Merges the supplied maps into <code>zero</code> using a left to right fold of
     * {@link Map#putAll}.
     */
    public static <K, V, M extends Map<K, V>> M putAll (
        M zero, Iterable<Map<? extends K, ? extends V>> values)
    {
        for (Map<? extends K, ? extends V> value : values) {
            zero.putAll(value);
        }
        return zero;
    }
}

@@ -941,16 +941,43 @@
 ection;%0A
+import java.util.Iterator;%0A
 import j
@@ -1060,16 +1060,1091 @@
 Folds%0A%7B%0A
+    /** Used with %7B@link #foldLeft%7D. */%0A    public interface F%3CB,A%3E%0A    %7B%0A        /** Folds the supplied element into the result. */%0A        B apply (B zero, A elem);%0A    %7D%0A%0A    /** For reductions and same-typed folds. */%0A    public interface R%3CA%3E extends F%3CA,A%3E %7B%7D%0A%0A    /**%0A     * Left folds the supplied function over the supplied values using the supplied starting value.%0A     */%0A    public static %3CA, B%3E B foldLeft (F%3CB,A%3E func, B zero, Iterable%3C? extends A%3E values)%0A    %7B%0A        for (A value : values) %7B%0A            zero = func.apply(zero, value);%0A        %7D%0A        return zero;%0A    %7D%0A%0A    /**%0A     * Reduces the supplied values using the supplied function with a left fold.%0A     *%0A     * @exception NoSuchElementException thrown if values does not contain at least one element.%0A     */%0A    public static %3CA%3E A reduceLeft (F%3CA,A%3E func, Iterable%3C? extends A%3E values)%0A    %7B%0A        Iterator%3CA%3E iter = values.iterator();%0A        A zero = iter.next();%0A        while (iter.hasNext()) %7B%0A            zero = func.apply(zero, iter.next());%0A        %7D%0A        return zero;%0A    %7D%0A%0A
     /**%0A

Let's go ahead and add general fold and reduce even though I've held off on adding a function type to samskivert because everyone and their mother has a function type. This is hopefully innocuous enough and allows you to obtain generality at the expense of verbosity: