An open API service indexing awesome lists of open source software.

https://github.com/xyzsd/dichotomy

Result, Either, Try, and Maybe monadic types for Java
https://github.com/xyzsd/dichotomy

adt algebraic-data-types either either-monad error-handling java jdk jvm maybe-monad monads railway-oriented-programming result result-monad result-type sealed-class sum-types try try-monad types

Last synced: about 1 month ago
JSON representation

Result, Either, Try, and Maybe monadic types for Java

Awesome Lists containing this project

README

        

[![Java CI with Gradle](https://github.com/xyzsd/dichotomy/actions/workflows/gradle.yml/badge.svg)](https://github.com/xyzsd/dichotomy/actions/workflows/gradle.yml)

# dichotomy
Sealed monads for Java.

Generally these types are used to return one of two values, such as success or failure.

All types are sealed (Sum types), and can be used in `switch` expressions and with
pattern matching.

### `Either`:
A general immutable type that can only be *either* one of two types.
The types are called `Left` and `Right`. By convention, the Left type
indicates failure, while the Right type indicates success.

### `Result`:
Similar to an `Either`, but with success/failure semantics more clearly defined.
An `OK` Result indicates success, and an `Err` Result indicates failure. Failure
types do not need to be Exceptions.

```java

Result result = Result.ofOK(3828) // returns an OK
.map(x -> x*10.0) // map to Result, after multiplying x 10
.match(System.out::println) // print "38280.0" to console
.matchErr(System.err::println); // ignored, as this is an OK

switch(result) {
case OK ok -> System.out.println("value ok! value: "+ok.value());
case Err err -> System.err.println(err.value());
}

// JDK 21+
switch(result) {
case OK(Double x) when x > 0 -> System.out.println("positive");
case OK(Double x) -> System.out.println("0 or negative");
case Err(String s) -> System.err.println(s);
}

// anotherResult here will be an Err
Result anotherResult = Result.ofErr("Insufficient entropy")
.map(x -> x*10.0 ) // ignored, as this is an Err
.match(System.out::println) // ignored, as this is an Err
.matchErr(System.err::println); // "Insufficient entropy" printed to System.err
```


### `Try`:
A specialized type of `Result`. A `Try` wraps a function or block; if
successful, a `Success` Try is returned; otherwise, a `Failure` Try containing
an Exception is returned. Intermediate operations which return Trys will also
catch generated Exceptions.

```java

final Try result = Try.ofSuccess( 777 )
.map( i -> i * 1000 ) // results in a Try with a value of 777000
.exec( System.out::println ) // prints "777000"
.map( i -> i / 0 ) // the ArithmeticException is caught as a Try.Failure
.exec( System.out::println ); // does not exec() because we are a Failure

// prints "ERROR: java.lang.ArithmeticException: / by zero"
switch(result) {
case Success(Integer i) -> System.out.printf("Operation completed successfully. Value: %d\n", i);
case Failure(Throwable t) -> System.err.printf("ERROR: %s\n", t);
}

```

### `Maybe`:
Analogous to the JDK `Optional` type, but sealed so it may be used in `switch`
statements and with pattern matching.

## Updates
### Branch 1.1 (August 2024, not yet released)
JSR-305 nullness annotations have been replaced with JSpecify 1.0, reducing annotation clutter.
Note that this could potentially pose problems given
[issues prior to JDK 22](https://jspecify.dev/docs/whether/#annotation-processors).
Runtime nullness checks (via Objects.requireNonNull) have not been removed.

The 1.1 branch also adds `Result::merge` which simplifies reduction operations on `Result` streams
(see method documentation and tests for examples).

### Release 1.0 (January 2024)
Refactored and improved from the original version.

Handling exceptions is substantially better with the new
`Try` type (a specialized type of `Result`), which also
supports the try-with-resources pattern.

Some usage examples are now included... though additional
illustrative examples should be provided!

Documentation
-------------
[Available online][doc_online] or by [download][doc_download].

Download
--------
depend via Maven:

```xml

net.xyzsd
dichotomy
1.0
module

```

or Gradle:
```kotlin
implementation("net.xyzsd:dichotomy:1.0")
```

or [download](https://github.com/xyzsd/dichotomy/releases/tag/1.0) from GitHub.

License
-------
Copyright 2022-2024, xyzsd

Many thanks to [@fdelsert](https://github.com/fdelsert) for
suggestions and improvements leading to the 1.0 release.

Licensed under either of:

* Apache License, Version 2.0
(see LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
* MIT license
(see LICENSE-MIT) or http://opensource.org/licenses/MIT)

at your option.

[doc_online]: https://javadoc.io/doc/net.xyzsd/dichotomy/1.0/index.html
[doc_download]: https://github.com/xyzsd/dichotomy/releases/download/1.0/dichotomy-1.0-javadoc.jar