package cs2030s.fp; /** * A container class the encapsulate * a value that may or may not be an error. * * @author Adi Yoga S. Prabawa * @version CS2030S AY 22/23 Sem 1 */ public class Actually implements Immutatorable { private T val; private Exception err; private Actually(T val, Exception err) { this.val = val; this.err = err; } public static Actually err() { // A common error for ease of use return new Actually((T) null, new Exception("err")); } public static Actually err(Exception err) { return new Actually((T) null, err); } public static Actually ok(T val) { return new Actually(val, null); } public T except(Constant com) { return this.err == null ? this.val : com.init(); } public T unless(U val) { return this.err == null ? this.val : val; } public void finish(Action act) { if (this.err == null) { act.call(this.val); } } @Override public Actually transform(Immutator f) { return this.err == null ? Actually.ok(f.invoke(this.val)) : Actually.err(this.err); } public Actually next(Immutator, ? super T> f) { if (this.err != null) { return Actually.err(this.err); } else { return f.invoke(this.val); } } public Actually check(Immutator pred) { if (this.err != null) { return Actually.err(this.err); } Boolean chk = pred.invoke(this.val); if (chk) { return this; } return Actually.err(); } @Override public String toString() { if (this.err != null) { return "<>"; } return "<" + this.val + ">"; } @Override public boolean equals(Object obj) { if (obj == this) { return true; } if (!(obj instanceof Actually)) { return false; } Actually that = (Actually) obj; if (this.err != null) { // for simplicity, all err is the same return that.err != null; } if (this.val == null) { return that.val == null; } return this.val.equals(that.val); } }