package cs2030s.fp; /** * A container class the encapsulate a * lazily-evaluated-and-memoized value. * * @author Adi Yoga S. Prabawa * @version CS2030S AY 22/23 Sem 1 */ public class Memo implements Immutatorable { private Constant com; private Actually val; private Memo(Actually val, Constant com) { this.com = com; this.val = val; } public static Memo from(T val) { return new Memo(Actually.ok(val), null); } public static Memo from(Constant com) { return new Memo(Actually.err(), com); } public T get() { this.eval(); return this.val.unless(null); } private void eval() { if (this.com != null) { this.val = Actually.ok(this.com.init()); this.com = null; } } @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()); } public Memo combine(Memo snd, Combiner f) { return Memo.from(() -> f.combine(this.get(), snd.get())); } public Memo check(Immutator pred) { return Memo.from(() -> pred.invoke(this.get())); } @Override public String toString() { if (this.com != null) { return "?"; } return this.get().toString(); } @Override public boolean equals(Object obj) { if (obj == this) { return true; } if (!(obj instanceof Memo)) { return false; } Memo that = (Memo) obj; that.eval(); this.eval(); return this.val.equals(that.val); } }