Skip to content

Instantly share code, notes, and snippets.

@jmspiewak
Created March 27, 2017 15:40
Show Gist options
  • Save jmspiewak/d6de2fefa20cc2e63b9368cd7d82c694 to your computer and use it in GitHub Desktop.
Save jmspiewak/d6de2fefa20cc2e63b9368cd7d82c694 to your computer and use it in GitHub Desktop.

Monads for Java programmers

Imagine Optional and Stream had two additional methods each:

class Optional<T> {
    // the usual Optional stuff
    // ...

    public static <T> Optional<T> pure(T x) {
        return Optional.of(x);
    }

    public <U> Optional<U> bind(Function<T, Optional<U>> f) {
        return flatMap(f);
    }
}
class Stream<T> {
    // ...

    public static <T> Stream<T> pure(T x) {
        return Stream.of(x);
    }

    public <U> Stream<U> bind(Function<T, Stream<U>> f) {
        return flatMap(f);
    }
}

Now try to imagine an interface X (with methods pure and bind), which could be implemented by both Optional and Stream.

X = Monad

Can't imagine this interface? Don't worry, it can't be expressed in Java.

Conclusion

In Java monad is a design pattern, while in Haskell it's a type class.

Monad Laws (extracurricular)

Every instance M of Monad must obey the following laws:

M.pure(a).bind(k) = k.apply(a)
m.bind(M::pure) = m
m.bind(x -> k.apply(x).bind(h)) = m.bind(k).bind(h)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment