179 lines
4.0 KiB
Java
179 lines
4.0 KiB
Java
package cs2030s.fp;
|
|
|
|
public abstract class Actually<T> implements Immutatorable<T>, Actionable<T> {
|
|
|
|
public static <T> Actually<T> ok(T value) {
|
|
return new Success<T>(value);
|
|
}
|
|
|
|
public static <T> Actually<T> err(Exception e) {
|
|
// It is okay to do an unchecked cast here as failure types don't use
|
|
// the value T.
|
|
@SuppressWarnings("unchecked")
|
|
Actually<T> failure = (Actually<T>) new Failure(e);
|
|
return failure;
|
|
}
|
|
|
|
public abstract T unwrap() throws Exception;
|
|
|
|
public abstract <U extends T> T except(Constant<? extends U> c);
|
|
|
|
public abstract void finish(Action<? super T> action);
|
|
|
|
public abstract <U extends T> T unless(U other);
|
|
|
|
public abstract <R> Actually<R> next(
|
|
Immutator<? extends Actually<? extends R>, ? super T> immutator);
|
|
|
|
private static class Success<T> extends Actually<T> {
|
|
private final T value;
|
|
|
|
private Success(T value) {
|
|
this.value = value;
|
|
}
|
|
|
|
@Override
|
|
public T unwrap() {
|
|
return this.value;
|
|
}
|
|
|
|
@Override
|
|
public <U extends T> T except(Constant<? extends U> c) {
|
|
return this.value;
|
|
}
|
|
|
|
@Override
|
|
public void finish(Action<? super T> action) {
|
|
action.call(this.value);
|
|
}
|
|
|
|
@Override
|
|
public <U extends T> T unless(U other) {
|
|
return this.value;
|
|
}
|
|
|
|
@Override
|
|
public <R> Actually<R> next(Immutator<? extends Actually<? extends R>, ? super T> immutator) {
|
|
try {
|
|
// it is okay to cast from <? extends R> to <R>
|
|
@SuppressWarnings("unchecked")
|
|
Actually<R> result = (Actually<R>) immutator.invoke(this.value);
|
|
return result;
|
|
} catch (Exception e) {
|
|
return Actually.err(e);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public <R> Actually<R> transform(Immutator<? extends R, ? super T> immutator) {
|
|
try {
|
|
return Actually.ok(immutator.invoke(this.value));
|
|
} catch (Exception e) {
|
|
return Actually.err(e);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void act(Action<? super T> action) {
|
|
action.call(this.value);
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return "<" + value + ">";
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(Object obj) {
|
|
if (obj == this) {
|
|
return true;
|
|
}
|
|
if (obj instanceof Success<?>) {
|
|
Success<?> other = (Success<?>) obj;
|
|
if (this.value == other.value) {
|
|
return true;
|
|
}
|
|
if (this.value != null && this.value.equals(other.value)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
}
|
|
|
|
private static class Failure extends Actually<Object> {
|
|
private final Exception e;
|
|
|
|
Failure(Exception e) {
|
|
this.e = e;
|
|
}
|
|
|
|
@Override
|
|
public Object unwrap() throws Exception {
|
|
throw e;
|
|
}
|
|
|
|
@Override
|
|
public <U> U except(Constant<? extends U> c) {
|
|
return c.init();
|
|
}
|
|
|
|
@Override
|
|
public Object unless(Object other) {
|
|
return other;
|
|
}
|
|
|
|
@Override
|
|
public void finish(Action<? super Object> action) {
|
|
return;
|
|
}
|
|
|
|
@Override
|
|
public <R> Actually<R> transform(Immutator<? extends R, ? super Object> immutator) {
|
|
return Actually.err(this.e);
|
|
}
|
|
|
|
@Override
|
|
public <R> Actually<R> next(
|
|
Immutator<? extends Actually<? extends R>, ? super Object> immutator) {
|
|
return Actually.err(this.e);
|
|
|
|
}
|
|
|
|
@Override
|
|
public void act(Action<? super Object> action) {
|
|
// Do nothing
|
|
return;
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return "[" + e.getClass().getName() + "] " + e.getMessage();
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(Object obj) {
|
|
if (obj == this) {
|
|
return true;
|
|
}
|
|
if (obj instanceof Failure) {
|
|
Failure other = (Failure) obj;
|
|
if (this.e == other.e) {
|
|
return true;
|
|
}
|
|
if (this.e == null || other.e == null) {
|
|
return false;
|
|
}
|
|
if (this.e.getMessage() == null || other.e.getMessage() == null) {
|
|
return false;
|
|
}
|
|
return this.e.getMessage() == other.e.getMessage();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
}
|
|
|
|
}
|