λdmx-fun
Explicit types for failures, absence, and validation in Java.
Composable via map and flatMap. Pattern-matchable via sealed interfaces.
Eliminate NullPointerException
Option<T> makes absence explicit in the type system. Callers cannot forget the empty case — the compiler enforces it.
Typed failures, not exceptions
Result<V, E> returns both the happy path and the domain error as values. No more swallowed catch blocks or undocumented throws.
Compose with map and flatMap
Every type — Option, Result, Try, Validated — exposes the same composable API. Learn once, apply everywhere.
Core types
Full reference →Eight composable types — each with a clear purpose and a consistent API.
Option<T> Nullability A value that may or may not be present. The null-safe alternative.
Result<V, E> Error handling Either a success value or a typed error. Models domain failures explicitly.
Try<V> Exception handling Wraps a computation that may throw. Turns exceptions into values.
Validated<E, A> Validation Like Result but accumulates multiple errors instead of failing fast.
Either<L, R> Disjoint union A neutral disjoint union with no success/failure semantics.
Lazy<T> Deferred computation A value computed at most once, on first access. Thread-safe memoization.
Tuple2/3/4 Product types Typed heterogeneous tuples. Named fields without a dedicated class.
NonEmptyList<T> Collections A list guaranteed to have at least one element at compile time.
Quick example
Combining types →import dmx.fun.Option;import dmx.fun.Try;import java.util.function.Function;
public class QuickExample { record User(String name, String email, String password) { }
Function<String, Option<User>> findUser = email -> Option.some(new User("User", email, "secret"));
private String getUserName(String email) { // Handle options safely return findUser.apply(email) .map(User::name) .getOrElse("Anonymous"); }
private void parseInt(String name) { // Handle errors functionally Try.of(() -> Integer.parseInt(name)) .recover(throwable -> { System.out.println("Error parsing: " + throwable.getMessage()); return 0; }) .onSuccess(System.out::println); }}Optional modules
All modules →Independent artifacts — add only what you need.
fun-jackson JSON Serializers and deserializers for all dmx-fun types via Jackson.
codes.domix:fun-jackson fun-assertj Testing Fluent AssertJ custom assertions for all dmx-fun types.
codes.domix:fun-assertj fun-spring Spring Transactional support for Result and Try — rolls back on error without throwing exceptions.
codes.domix:fun-spring Installation
Full setup →Available on Maven Central. Add a single dependency to get started.
implementation("codes.domix:fun:LATEST_VERSION")<dependency> <groupId>codes.domix</groupId> <artifactId>fun</artifactId> <version>LATEST_VERSION</version></dependency>Ready to dive in?
The Developer Guide covers every type in depth — design rationale, every combinator, composition patterns, and pitfalls to avoid.