package cs2030s.fp; public class Memo extends Lazy { private Actually value; protected Memo(Constant c) { super(c); // if actually is err, it is uninitialised this.value = Actually.err(null); } protected Memo(T v) { super(() -> v); this.value = Actually.ok(v); } public static Memo from(T v) { return new Memo(v); } public static Memo from(Constant v) { return new Memo(v); } public T get() { T result = this.value.except(() -> super.get()); this.value = Actually.ok(result); return result; } public Memo combine( Memo other, Combiner combiner) { return Memo.from(() -> combiner.combine(this.get(), other.get())); } @Override public Memo transform(Immutator f) { return Memo.from(() -> f.invoke(this.get())); } public Memo next(Immutator, ? super T> f) { return Memo.from(() -> f.invoke(this.get()).get()); } @Override public String toString() { return this.value.next(t -> Actually.ok(String.valueOf(t))).unless("?"); } }