/*
 * @author Ranides Atterwim <ranides@gmail.com>
 * @copyright Ranides Atterwim
 * @license WTFPL
 * @url http://ranides.net/projects/assira
 */
package net.ranides.assira.functional;

import java.util.Iterator;
import java.util.function.BinaryOperator;

/**
 *
 * @author Ranides Atterwim <ranides@gmail.com>
 */
@FunctionalInterface
public interface Fold<T> extends BinaryOperator<T> {

    @Override
    T apply(T a, T b);
    
    default T apply(Iterator<T> iterator) {
        return apply(iterator, this);
    }
    
    default T apply(T[] array) {
        return apply(array, this);
    }
    
    static <T> T apply(Iterator<T> iterator, BinaryOperator<T> operator) {
        T ret = iterator.next();
        while(iterator.hasNext()) {
            ret = operator.apply(ret, iterator.next());
        }
        return ret;
    }
    
    static <T> T apply(T[] array, BinaryOperator<T> operator) {
        T ret = array[0];
        for(int i=1; i<array.length; i++) {
            ret = operator.apply(ret, array[i]);
        }
        return ret;
    }
    
}
