namespace Invercargill { public abstract class NumberEnumerable : StickyPromotion, Promotion, Equatable> { protected abstract bool greater_than(T a, T b); protected abstract bool less_than(T a, T b); protected abstract bool equal_to(T a, T b); protected abstract T add(T a, T b); protected abstract T subtract(T a, T b); protected abstract T multiply(T a, T b); protected abstract T divide(T a, T b); protected abstract T zero(); protected abstract T convert(int i); public virtual T average() { return divide(sum(), convert(count())); } public virtual T sum() { return aggrigate(zero(), add); } public virtual T product() { T number = zero(); var first = true; foreach (var item in this) { if(first) { first = false; number = item; continue; } number = multiply(number, item); } return number; } public new virtual T min() { T value = null; var first = true; foreach (var i in this) { if(first) { first = false; value = i; continue; } if(less_than(i, value)) { value = i; } } return value; } public new virtual T max() { T value = null; var first = true; foreach (var i in this) { if(first) { first = false; value = i; continue; } if(greater_than(i, value)) { value = i; } } return value; } public override Enumerable wrap (Enumerable enumerable) { inner = enumerable; return this; } public bool equals(Enumerable other) { return this == other || this.matches(other, (a, b) => equal_to(a, b)); } } }