An Either Monad in Java Interested in a review of this code, in particular the (hopefully monadic) bind. I actually put this to good use. It was a nice complement to Guava's Optional, and shorter than:


  Optional.fromNullable(x).or(y);


And I threw in a bind method, which I think lifts it up into monad space.

One question I wasn't sure of the the semantics of multiple calls. Should I carry along the original default value, or does each new value become the default? So in psuedo code, should


  Either.with("A").or("B").or(null)


result in "A" (the original default) or "B"? I thought "B" made more sense.

I'm interested in if I got the monad signature &amp; semantics right.

public class Either&lt;A&gt; {

    private final A value;

    /**
     * constructor sets the default &amp; value the same
     * @param defaultValue
     */
    Either(A value) {
        if (value == null) {
            throw new IllegalArgumentException("Either cannot be null");
        }
        this.value = value;
    }

    /**
     * constructor sets the default &amp; value the same
     * @param defaultValue
     */
    Either(A defaultValue, A value) {
        this.value = (value == null) ? defaultValue : value;
    }

    /**
     * the unit method lifts the value into the monadic space
     * 
     * @param value
     * @return an either with the value as default
     */
    public static &lt;A&gt; Either&lt;A&gt; with(A value) {
        return new Either&lt;A&gt;(value);
    }

    /**
     * create a new either using the previous default
     * 
     * @param value
     * @return
     */
    public Either&lt;A&gt; or(A value) {
        return new Either&lt;A&gt;(this.value, value);
    }

    /**
     * @return the value, or the default
     */
    public A get() {
        return value;
    }

    /**
     * completes this class as a monad
     * 
     * @param f
     * @return an either of the new type
     */
    public &lt;B&gt; Either&lt;B&gt; bind(Function&lt;A, Either&lt;B&gt;&gt; f) {
        return f.apply(value);
    }
}


And here are the unit tests for bind (and sample usage):

static class ToInt implements Function&lt;String, Either&lt;Integer&gt;&gt; {

    private final int defaultInt;

    /**
     * lol closures in java
     * 
     * @param defaultInt
     */
    public ToInt(int defaultInt) {
        this.defaultInt = defaultInt;
    }

    @Override
    public Either&lt;Integer&gt; apply(String s) {
        try {
            return Either.with(Integer.parseInt(s));
        }
        catch (NumberFormatException nfe) {
            return Either.with(defaultInt);
        }
    }
};

private static final Function&lt;Integer, Either&lt;Double&gt;&gt; SQRT = new Function&lt;Integer, Either&lt;Double&gt;&gt;() {
    @Override
    public Either&lt;Double&gt; apply(Integer i) {
        return Either.with(Math.sqrt(i));
    }
};

private static final int TEN_THOUSAND = 10000;
private final ToInt TO_INT = new ToInt(TEN_THOUSAND);

// ~=~=~=~=~=~=~=~=~=~=
// Tests


public void bindToIntEmptyEXPECTDefault() {
    // Arrange
    Either&lt;String&gt; a = Either.with("");

    // Act
    Either&lt;Double&gt; b = a.bind(TO_INT).bind(SQRT);

    // Assert
    assertEquals(b.get(), 100.0);
}

public void bindToIntFormatEXPECTDefault() {
    // Arrange
    Either&lt;String&gt; a = Either.with("zoom");

    // Act
    Either&lt;Double&gt; b = a.bind(TO_INT).bind(SQRT);

    // Assert
    assertEquals(b.get(), 100.0);
}

public void bindToIntEXPECTInt() {
    // Arrange
    Either&lt;String&gt; a = Either.with("144");

    // Act
    Either&lt;Double&gt; b = a.bind(TO_INT).bind(SQRT);

    // Assert
    assertEquals(b.get(), 12.0);
}
I have a nit-pick with the logic in your Either.or(A) method. You have:


public Either&lt;A&gt; or(A value) {
    return new Either&lt;A&gt;(this.value, value);
}



but, since Either is immutable (oh, should Either be a final class? ... I think so...), it makes sense that the or method can return the exact instance if it is valid.... why does it have to create a new instance each time? In a stream that can create a lot of GC churn....

I would write that method:

public Either&lt;A&gt; or(A value) {
    return value == null ? this : new Either&lt;A&gt;(value);
}


I know that essentially duplicates the constructor, but, doing it this way avoids the constructor in (hopefully) many places entirely.

This leads on to your question:


  One question I wasn't sure of the the semantics of multiple calls.
  Should I carry along the original default value, or does each new
  value become the default? So in psuedo code, should

Either.with("A").or("B").or(null)

  
  result in "A" (the original default) or "B"? I thought "B" made more
  sense.


If the or(A) method does not need to construct a new instance, then it makes sense to me that the semantics should return "A", since that allows skipping new instances for "B" and null.