nus/Lab7/cs2030s/fp/Actually.java
2022-11-08 18:03:40 +08:00

89 lines
2.2 KiB
Java

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<T> implements Immutatorable<T> {
private T val;
private Exception err;
private Actually(T val, Exception err) {
this.val = val;
this.err = err;
}
public static <T> Actually<T> err() {
// A common error for ease of use
return new Actually<T>((T) null, new Exception("err"));
}
public static <T> Actually<T> err(Exception err) {
return new Actually<T>((T) null, err);
}
public static <T> Actually<T> ok(T val) {
return new Actually<T>(val, null);
}
public T except(Constant<? extends T> com) {
return this.err == null ? this.val : com.init();
}
public <U extends T> T unless(U val) {
return this.err == null ? this.val : val;
}
public void finish(Action<? super T> act) {
if (this.err == null) {
act.call(this.val);
}
}
@Override
public <R> Actually<R> transform(Immutator<? extends R, ? super T> f) {
return this.err == null ? Actually.<R>ok(f.invoke(this.val)) : Actually.<R>err(this.err);
}
public <R> Actually<? extends R> next(Immutator<? extends Actually<? extends R>, ? super T> f) {
if (this.err != null) {
return Actually.err(this.err);
} else {
return f.invoke(this.val);
}
}
public Actually<T> check(Immutator<Boolean, ? super T> pred) {
if (this.err != null) {
return this;
}
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);
}
}