Skip to content

Instantly share code, notes, and snippets.

@esfand
Last active August 29, 2015 14:02
Show Gist options
  • Save esfand/4fcf533f6589e11bc760 to your computer and use it in GitHub Desktop.
Save esfand/4fcf533f6589e11bc760 to your computer and use it in GitHub Desktop.
Monadic Java

What is a monad?

A monad is a triple (T, η, μ) where

  • T is an endofunctor T: X -> X and
  • η: I -> T and μ: T x T -> T are 2 natural transformations satisfying these laws:
    • Identity law: μ(η(T)) = T = μ(T(η))
    • Associative law: μ(μ(T × T) × T)) = μ(T × μ(T × T))

In other words:

a monad in X is just a monoid in the category of endofunctors of X, with

  • product × replaced by composition of endofunctors and
  • unit set by the identity endofunctor

In other words:

A monad

  • is a structure that
  • puts a value
  • in a computational context

And therefore:

  • Reduce code duplication
  • Improve maintainability
  • Increase readability
  • Remove side effects
  • Hide complexity
  • Encapusalate implementation details
  • Allow composability

##Monadic Methods##

M<A> unit(A a);

M<B> bind(M<A> ma, Function<A, M<B>> f);
interface M {

    M<B> map(Function<A, B> f);
    //{
    //    // For every monad, map can be defined as a combination of flatMap and unit
    //    return flatMap( x -> unit( f.apply(x) ) );
    //}

    M<B> flatMap(Function<A, M<B>> f);
}
public class Optional<T> {

    private static final Optional<?> EMPTY = new Optional<>(null);

    private final T value;

    private Optional(T value) {

        this.value = value;
    }

    public<U> Optional<U> map (Function<? super T, ? extends U> f) {

        return value == null ? EMPTY : new Optional(f.apply(value));
    }

    public<U> Optional<U> flatMap (Function<? super T, Optional<U>> f) {

        return value == null ? EMPTY : f.apply(value);
    }
}

public class Optional {

private static final Optional<?> EMPTY = new Optional<>(null);

private final T value;

private Optional(T value) {
    this.value = value;
}

public<U> Optional<U> map(Function<? super T, ? extends U> f) {
    return value == null ? EMPTY : new Optional(f.apply(value));
}

public<U> Optional<U> flatMap(Function<? super T, Optional<U>> f) {
    return value == null ? EMPTY : f.apply(value);
}

}

String getCarInsuranceName(Optional<Person> person) {

    return person.flatMap(person -> person.getCar())
                 .flatMap(car -> car.getInsurance())
                 .map(insurance -> insurance.getName())
                 .orElse("Unknown");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment