Some functional sweetness for Java.

This library provides useful monads that are not present in the JDK. The defined types and API are minimal and highly composable with the standard ones, avoiding re-inventing them.


The Javadoc for the latest snapshot version is available online here.


The Attempt monad represents a computation which can be either successful or failed. It allows the transformation of results and the recovery of errors in a pipeline, similarly to Scala's Try or Java's CompletableFuture.

This monad does not require the error type to be a Throwable, the use of which being problematic in performance-sensitive contexts.

import static org.pacien.lemonad.attempt.Attempt.*;

(tree.hasLemon() ? success(tree.getLemon()) : failure("No lemon."))
  .recoverError(error -> store.buyLemon())


The Validation monad represents a validation of a subject which can be successful or failed with errors. Those errors are aggregated from all the checks that have failed.

import org.pacien.lemonad.validation.Validation;

  .validate(not(Lemon::isRotten), "Bad lemon.")
  .validate(Lemon::juiceContent, mL -> mL >= 40, "Not juicy")
  .ifInvalid(errors -> makeLifeTakeTheLemonBack());


lemonad requires Java 11 or above. Binaries are compiled by and distributed through JitPack.

Gradle (build.gradle)

repositories {
  maven { url 'https://jitpack.io' }

dependencies {
  implementation 'org.pacien:lemonad:7ded9823fb'

Maven (pom.xml)




Copyright (C) 2019 Pacien TRAN-GIRARD.

lemonad is distributed under the terms of GNU Affero General Public License v3.0, as detailed in the attached license.md file.