/* Result Monad in Modern Java (requires JDK 22+) */ import java.util.function.*; sealed interface Result permits OkResult, ErrResult { static Result Ok(V x) { return new OkResult(x); } static Result Err(E e) { return new ErrResult(e); } // switch can pattern-match on record types since JDK 21 default Result map(Function f) { return switch(this) { case OkResult(VT v) -> new OkResult(f.apply(v)); case ErrResult(ET e) -> new ErrResult(e); }; }//map default Result map_err(Function f) { return switch(this) { case OkResult(VT v) -> new OkResult(v); case ErrResult(ET e) -> new ErrResult(f.apply(e)); }; }//map_err default Result bind(Function> bf) { return switch(this) { case OkResult(VT v) -> bf.apply(v); case ErrResult(ET e) -> new ErrResult(e); }; }//bind (flatMap for java.util.Optional) default Result and_then(Function> bf) { return this.bind(bf); } // alias for bind default void if_ok(Consumer action) { switch (this) { case OkResult(VT v): action.accept(v); break; case ErrResult(_) : break; // _ available since JDK 22 } }//if_ok default void if_else(Consumer a, Consumer b) { switch (this) { case OkResult(VT v): a.accept(v); break; case ErrResult(ET e) : b.accept(e); break; } }//if_else default boolean is_ok() { return switch(this) { case OkResult(_) -> true; case ErrResult(_) -> false; }; }//is_ok default boolean not_ok() { return !this.is_ok(); } default VT unwrap_or(VT id) { // no unwrap, just unwrap_or return switch(this) { case OkResult(VT v) -> v; case ErrResult(_) -> id; }; }//unwrap_or // short-circuited or over two results default Result or(Result other) { return switch(this) { case OkResult(_) -> this; case ErrResult(_) -> other; }; } //Adopts a supplier function to return a result instead of throwing an //exception: the exception's error message is returned in an ErrResult. //Also prohibits null. static Result on_behalf(Supplier s) { Result answer; try { var x = s.get(); if (x==null) answer = Result.Err("null intercepted by on_behalf"); else answer = Result.Ok(x); } catch (Exception e) { answer = Result.Err("Exception caught by on_behalf:\n "+e); } return answer; }//on_behalf private VT unwrap() { return this.unwrap_or(null); } // internal use only! static Result flatten(Result,E> r) { return switch (r) { //case OkResult(OkResult(x)) -> r.unwrap_or(null); case OkResult(OkResult(_)) -> r.unwrap(); case OkResult(ErrResult(_)) -> r.unwrap(); case ErrResult(E e) -> new ErrResult(e); }; }//flatten }//interface Result record OkResult(VT val) implements Result { @Override public String toString() { return "Ok("+val+")"; } } record ErrResult(ET err) implements Result { @Override public String toString() { return "Error("+err+")"; } } public class newresult { //// testing static Result safediv(Double x, Double y) { if (y!=0) return Result.Ok(x/y); else return Result.Err("div "+x+" by zero"); } static Result parsearg(String[] args, int i) { return Result.on_behalf(() -> Double.parseDouble(args[i])); } public static void main(String[] args) { var result = parsearg(args,0) .or(Result.on_behalf(() -> (double)Integer.parseInt(args[0],16))) .or(Result.Ok(0.0)) .map(x -> 2*x) .and_then(x -> parsearg(args,1) .and_then(y -> safediv(x,y))); System.out.println(result); }//main } ///// Class adapter: update old java to new: class SafeStack { private java.util.Stack inner; public SafeStack() { inner = new java.util.Stack(); } public boolean empty() { return inner.empty(); } public int size() { return inner.size(); } public Result push(T item) { return Result.on_behalf(() -> inner.push(item)); } public Result pop() { return Result.on_behalf(() -> inner.pop()); }//pop public Result peek() { return Result.on_behalf(() -> inner.peek()); }//peek public int Search(Object x) { if (x!=null) return inner.search(x); else return -1; } }