package com.googlecode.totallylazy.numbers;
import com.googlecode.totallylazy.functions.CurriedMonoid;
public class Average implements CurriedMonoid<Number> {
public Number call(Number average, Number value) {
return weighted(average).combine(weighted(value));
}
@Override
public Number identity() {
return weighted(0, 0);
}
public static Weighted weighted(Number number, Number count) {
return new Weighted(number, count);
}
public static Weighted weighted(Number number) {
if (number instanceof Weighted) return (Weighted) number;
return weighted(number, 1);
}
private static class Weighted extends Num {
private final Num weight;
private Weighted(Number value, Number weight) {
super(value);
this.weight = num(weight);
}
public Weighted combine(Weighted value) {
Num newWeight = weight.add(value.weight);
return weighted(sum().add(value.sum()).divide(newWeight), newWeight);
}
private Num sum() {
return weight.multiply(value());
}
}
}