Example Maybe Monad in Java

Maybe.java

package net.faustinelli.monad.maybe;

import net.faustinelli.closures.F;

public abstract class Maybe<A> {

public abstract A value();

public static <A> Maybe<A> unit(A anA) {
if (anA == null)
return new Nothing<A>();
else
return new Just<A>(anA);
}

// bind instance method (F : A -> Maybe<B>)
public <B> Maybe<B> bind(F<A, Maybe<B>> famb) {
if (this instanceof Nothing<?>)
return new Nothing<B>();
else {
Just<A> self = (Just<A>) this;
return famb.f(self.aValue);
}
}

public static <A, B> F<Maybe<A>, Maybe<B>> map(final F<A, B> fab) {
return new F<Maybe<A>, Maybe<B>>() {
public Maybe<B> f(final Maybe<A> ma) {
return Maybe.unit(fab.f(ma.value()));
}
};
}

/**
*the check A instanceof Maybe<?> is impossible, therefore I need a litte trick: A is in fact a Maybe<A>
* @param <A>
* relevant only if Maybe<Maybe<A>>
*/
@SuppressWarnings("unchecked")
public static <A> Maybe<A> join(Maybe<A> mma) {
try {
// please find me some usage for this garbled thing!!!
return Maybe.unit(((Maybe<A>) mma.value()).value());
} catch (NullPointerException e) {
return new Nothing<A>();
}
}

public <B> Maybe<B> goBackTo(final Maybe<B> mb) {
return this.bind(new F<A, Maybe<B>>() {
public Maybe<B> f(A anA) {
return mb;
}
});
}
}


Just.java

package net.faustinelli.monad.maybe;

public class Just<A> extends Maybe<A> {
public A aValue;

public Just(A anA) {
aValue = anA;
}

@Override
public A value() {
return aValue;
}
}



Nothing.java

package net.faustinelli.monad.maybe;

public class Nothing<A> extends Maybe<A> {
public A value() {
return null;
}
}


Advertisements

3 thoughts on “Example Maybe Monad in Java

    1. faustinelli says:

      Well, it is a clumsy attempt to model an AND condition. Basically a goBackTo chains back to a previously mentioned Maybe. For example, if we want to express whether both male grandparents are alive, we may use two binding functions Maternity and Paternity, chaining Maybe’s. Then the chain would be:

      Maybe son = Maybe.unit(new Person(“marco”, Gender.MALE));
      Maybe bothGranpasAlive = son.bind(new Paternity()).bind(new Paternity()).goBackTo(son).bind(new Maternity()).bind(new Paternity());

      Then I check: bothGranpasAlive instanceOf Just

      But I don’t like all this, because only the second granpa would be given as result. Is there a way to carry more and more granpas along the way? I guess I should use something like a Maybe<List>, but I can’t yet see how to create a bind&carry function. Have you got any idea?

  1. Spencer Tipping says:

    Very nice implementation! I had tried just a little bit to get the types to work out in my own monad library, but had trouble propagating the variance through to the Monad interface. I like the way you’ve encapsulated functions — I think it solves the problem very well.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s