Try monad in Java 8

后端 未结 6 2059
甜味超标
甜味超标 2020-12-30 04:15

Is there a built-in support for monad that deals with exception handling? Something similar to Scala\'s Try. I am asking because I don\'t like unchecked exceptions.

6条回答
  •  自闭症患者
    2020-12-30 05:14

    Here there is an implementation that could be used as a model. Further information can be found here:

    Java with Try, Failure, and Success based computations

    You can basically do something like this:

    public class Test {
    
      public static void main(String[] args) {
    
        ITransformer < String > t0 = new ITransformer < String > () {@
          Override
          public String transform(String t) {
            //return t + t;
            throw new RuntimeException("some exception 1");
          }
        };
    
        ITransformer < String > t1 = new ITransformer < String > () {@
          Override
          public String transform(String t) {
            return "<" + t + ">";
            //throw new RuntimeException("some exception 2");
          }
        };
    
        ComputationlResult < String > res = ComputationalTry.initComputation("1").bind(t0).bind(t1).getResult();
    
        System.out.println(res);
    
        if (res.isSuccess()) {
          System.out.println(res.getResult());
        } else {
          System.out.println(res.getError());
        }
      }
    }
    

    And here is the code:

    public class ComputationalTry < T > {
    
      final private ComputationlResult < T > result;
    
      static public < P > ComputationalTry < P > initComputation(P argument) {
        return new ComputationalTry < P > (argument);
      }
    
      private ComputationalTry(T param) {
        this.result = new ComputationalSuccess < T > (param);
      }
    
      private ComputationalTry(ComputationlResult < T > result) {
        this.result = result;
      }
    
      private ComputationlResult < T > applyTransformer(T t, ITransformer < T > transformer) {
        try {
          return new ComputationalSuccess < T > (transformer.transform(t));
        } catch (Exception throwable) {
          return new ComputationalFailure < T, Exception > (throwable);
        }
      }
    
      public ComputationalTry < T > bind(ITransformer < T > transformer) {
        if (result.isSuccess()) {
          ComputationlResult < T > resultAfterTransf = this.applyTransformer(result.getResult(), transformer);
          return new ComputationalTry < T > (resultAfterTransf);
        } else {
          return new ComputationalTry < T > (result);
        }
      }
    
      public ComputationlResult < T > getResult() {
        return this.result;
      }
    }
    
    
    public class ComputationalFailure < T, E extends Throwable > implements ComputationlResult < T > {
    
      public ComputationalFailure(E exception) {
        this.exception = exception;
      }
    
      final private E exception;
    
      @Override
      public T getResult() {
        return null;
      }
    
      @Override
      public E getError() {
        return exception;
      }
    
      @Override
      public boolean isSuccess() {
        return false;
      }
    
    }
    
    
    public class ComputationalSuccess < T > implements ComputationlResult < T > {
    
      public ComputationalSuccess(T result) {
        this.result = result;
      }
    
      final private T result;
    
      @Override
      public T getResult() {
        return result;
      }
    
      @Override
      public Throwable getError() {
        return null;
      }
    
      @Override
      public boolean isSuccess() {
        return true;
      }
    }
    
    
    public interface ComputationlResult < T > {
    
      T getResult();
    
      < E extends Throwable > E getError();
    
      boolean isSuccess();
    
    }
    
    
    public interface ITransformer < T > {
    
      public T transform(T t);
    
    }
    
    
    public class Test {
    
      public static void main(String[] args) {
    
        ITransformer < String > t0 = new ITransformer < String > () {@
          Override
          public String transform(String t) {
            //return t + t;
            throw new RuntimeException("some exception 1");
          }
        };
    
        ITransformer < String > t1 = new ITransformer < String > () {@
          Override
          public String transform(String t) {
            return "<" + t + ">";
            //throw new RuntimeException("some exception 2");
          }
        };
    
        ComputationlResult < String > res = ComputationalTry.initComputation("1").bind(t0).bind(t1).getResult();
    
        System.out.println(res);
    
        if (res.isSuccess()) {
          System.out.println(res.getResult());
        } else {
          System.out.println(res.getError());
        }
      }
    }
    

    I hope this might shade some light.

提交回复
热议问题