Monads with Java 8

Tags: , , ,



In the interests of helping to understand what a monad is, can someone provide an example using java ? Are they possible ?

Lambda expressions are possible using java if you download the pre-release lambda compatible JDK8 from here http://jdk8.java.net/lambda/

An example of a lambda using this JDK is shown below, can someone provide a comparably simple monad ?

public interface TransformService {
        int[] transform(List<Integer> inputs);
    }
    public static void main(String ars[]) {
        TransformService transformService = (inputs) -> {
            int[] ints = new int[inputs.size()];
            int i = 0;
            for (Integer element : inputs) {
                ints[i] = element;
            }
            return ints;
        };

        List<Integer> inputs = new ArrayList<Integer>(5) {{
            add(10);
            add(10);
        }};
        int[] results = transformService.transform(inputs);
    }

Answer

Just FYI:

The proposed JDK8 Optional class does satisfy the three Monad laws. Here’s a gist demonstrating that.

All it takes be a Monad is to provide two functions which conform to three laws.

The two functions:

  1. Place a value into monadic context

    • Haskell’s Maybe: return / Just
    • Scala’s Option: Some
    • Functional Java’s Option: Option.some
    • JDK8’s Optional: Optional.of
  2. Apply a function in monadic context

    • Haskell’s Maybe: >>= (aka bind)
    • Scala’s Option: flatMap
    • Functional Java’s Option: flatMap
    • JDK8’s Optional: flatMap

Please see the above gist for a java demonstration of the three laws.

NOTE: One of the key things to understand is the signature of the function to apply in monadic context: it takes the raw value type, and returns the monadic type.

In other words, if you have an instance of Optional<Integer>, the functions you can pass to its flatMap method will have the signature (Integer) -> Optional<U>, where U is a value type which does not have to be Integer, for example String:

Optional<Integer> maybeInteger = Optional.of(1);

// Function that takes Integer and returns Optional<Integer>
Optional<Integer> maybePlusOne = maybeInteger.flatMap(n -> Optional.of(n + 1));

// Function that takes Integer and returns Optional<String>
Optional<String> maybeString = maybePlusOne.flatMap(n -> Optional.of(n.toString));

You don’t need any sort of Monad Interface to code this way, or to think this way. In Scala, you don’t code to a Monad Interface (unless you are using Scalaz library…). It appears that JDK8 will empower Java folks to use this style of chained monadic computations as well.

Hope this is helpful!

Update: Blogged about this here.



Source: stackoverflow