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
- Host: GitHub
- URL: https://github.com/xyzsd/dichotomy
- Owner: xyzsd
- License: other
- Created: 2022-06-07T17:45:02.000Z (almost 3 years ago)
- Default Branch: main
- Last Pushed: 2024-08-13T19:39:40.000Z (9 months ago)
- Last Synced: 2025-03-24T15:11:19.587Z (2 months ago)
- Topics: 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
- Language: Java
- Homepage:
- Size: 315 KB
- Stars: 32
- Watchers: 2
- Forks: 3
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE-APACHE
Awesome Lists containing this project
README
[](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 OKswitch(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, xyzsdMany 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