Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Try monad in Java 8

Tags:

monads

java-8

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.

like image 582
Jiri Kremser Avatar asked Jan 05 '15 20:01

Jiri Kremser


People also ask

What is a Monad in Java?

A monad is just a wrapper around a type or data structure. So by 'wrapping' a class type (e.g. Integer) inside the Java Optional type, we add some functionality around it, like of(x) , isPresent() , orElse(c) and get() . To be more precise, a Monad always contains a bind() function, That translates to flatMap in Java.

Is Java optional Monad?

Java 8 introduced Optional class which is a monad. It provides operational equivalent to a monad. For example return is a operation which takes a value and return the monad.

Is Java future a Monad?

Java's CompletableFuture is a Monad given its methods thenCompose and thenApply , which correspond to >>= (bind) and fmap in Haskell. It is a well known fact that any Monad gives rise to an Applicative.

What is try in Scala?

The Try type represents a computation that may either result in an exception, or return a successfully computed value. It's similar to, but semantically different from the scala. util. Either type. Instances of Try[T] , are either an instance of scala.


2 Answers

There are at least two generally available (e.g. on Maven Central) - Vavr and Cyclops both have Try implementations that take a slightly differing approach.

Vavr's Try follows Scala's Try very closely. It will catch all 'non-fatal' exceptions thrown during the execution of it's combinators.

Cyclops Try will only catch explicitly configured exceptions (of course you can, by default, also have it catch everything), and the default mode of operating is only to catch during the initial population method. The reasoning behind this is so that Try behaves in a somewhat similar way to Optional - Optional doesn't encapsulate unexpected Null values (i.e. bugs), just places where we reasonable expect to have no value.

Here is an example Try With Resources from Cyclops

 Try t2 = Try.catchExceptions(FileNotFoundException.class,IOException.class)
               .init(()->PowerTuples.tuple(new BufferedReader(new FileReader("file.txt")),new FileReader("hello")))
               .tryWithResources(this::read2);

And another example 'lifting' an existing method (that might divide by zero) to support error handling.

    import static org.hamcrest.Matchers.equalTo;
    import static org.junit.Assert.*;
    import static com.aol.cyclops.lambda.api.AsAnyM.anyM;
    import lombok.val;

    val divide = Monads.liftM2(this::divide);

    AnyM<Integer> result = divide.apply(anyM(Try.of(2, ArithmeticException.class)), anyM(Try.of(0)));

    assertThat(result.<Try<Integer,ArithmeticException>>unwrapMonad().isFailure(),equalTo(true));
 private Integer divide(Integer a, Integer b){
    return a/b;
 }
like image 107
John McClean Avatar answered Sep 28 '22 03:09

John McClean


The "better-java-monads" project on GitHub has a Try monad for Java 8 here.

like image 23
lbalazscs Avatar answered Sep 28 '22 03:09

lbalazscs