// Implementation of Result Monad in Java, by Chuck Liang, Hofstra University. // V is the type of values and E is the type of errors package ResultMonad; import java.util.function.*; public abstract class Result { // Abstract methods public abstract boolean is_ok(); public abstract V orElse(V Default); public abstract V getOr(Function errfun); public abstract Result map(Function f); // aka "flatMap" public abstract Result bind(Function> f); public abstract void ifOk(Consumer c); public abstract U match(Function okfun, Function errfun); public abstract void match_do(Consumer okfun, Consumer errfun); public abstract Result map_mutate(Function mut); // Non-abstract methods //provided functions: public Result flatMap(Function> f) { return bind(f); } // flatMap is alias for bind public static Result Ok(A v) { return new OkResult(v); }//static, polymorphic Ok public static Result Err(B e) { return new ErrResult(e); }//static, polymorphic Err // apply a function W*V -> U on two results @SuppressWarnings("unchecked") public Result chain(Result other, BiFunction binop) { return this.match( _ok1 -> other.map(_ok2 -> binop.apply(_ok1,_ok2)), _err -> (ErrResult)this //new ErrResult(_err) ); }//chain // if other result is Err, do not change current result public Result if_and(Result other, BiFunction binop) { return other.match( _ok -> this.map(_ok1 -> binop.apply(_ok1,_ok)), _err -> this ); }//if_and // combine two results into one for a pair (see pair.java in package) public Result,E> zip(Result second) { return this.bind(x -> second.bind(y -> Ok(new pair(x,y)))); }//zip (non-abstract) function // transform into java.util.Optional public java.util.Optional toOptional() { return this.match(_ok -> java.util.Optional.of(_ok), //ok err -> java.util.Optional.empty() //err ); }//toOptional }//Result abstract class