package highOrder;

import java.util.Iterator;
import java.util.List;

/**
 * Reduces a list to a single element. The type of the reduction is:
 * ('A * 'B -> 'B) -> 'B -> 'A list -> 'B
 * @author Fernando
 *
 * @param <A> The type of the elements of the list.
 * @param <B> The type of the result.
 */
public abstract class Reducer<A, B> {

  /**
   * Applies the reduction operation on the list.
   * @param l The list that will be reduced.
   * @param seed The initial value of the reduction operator.
   * @return
   */
  public final B reduce(final List<A> l, B acc) {
    Iterator<A> it = l.iterator();
    while (it.hasNext()) {
      acc = binOp(it.next(), acc);
    }
    return acc;
  }

  /**
   * This is the reduction operation that will be applied on the list.
   * @param elem An element of the list.
   * @param acc The accumulator.
   * @return
   */
  public abstract B binOp(A elem, B acc);

}
