Skip to content

Instantly share code, notes, and snippets.

@jdpage
Created June 30, 2012 18:42
Show Gist options
  • Save jdpage/3025041 to your computer and use it in GitHub Desktop.
Save jdpage/3025041 to your computer and use it in GitHub Desktop.
Playing Haskell (in Java)
class Add extends Func2<Integer, Integer, Integer> {
@Override
public Integer apply(Integer a, Integer b) {
return a + b;
}
}
abstract class Func<A, R> {
public abstract R apply(A a);
}
// utter syntactic sugar
abstract class Func2<A1, A2, R> extends Func<A1, Func<A2, R>> {
public abstract R apply(A1 a1, A2 a2);
@Override
public Func<A2, R> apply(final A1 a1) {
final Func2<A1, A2, R> func = this;
return new Func<A2, R>() {
@Override
public R apply(A2 a2) {
return func.apply(a1, a2);
}
};
}
}
class Maybe<A> extends Monad<A> {
public Maybe() {
super();
}
public Maybe(A a) {
super(a);
}
@Override
public <B> Monad<B> bind(Func<A, Monad<B>> f) {
if (value() == null)
return new Maybe<B>();
return f.apply(value());
}
}
class Monad<A> {
private A a;
public Monad() {
this.a = null;
}
public Monad(A a) {
this.a = a;
}
public <B> Monad<B> bind(Func<A, Monad<B>> f) {
return f.apply(a);
}
protected A value() {
return a;
}
public static <C, D> Func<C, Monad<D>> lift(final Func<C, D> f) {
return new Func<C, Monad<D>>() {
@Override public Monad<D> apply(C c) {
return new Monad<D>(f.apply(c));
}
};
}
}
// This program should print out "7" once and then exit
class Tester {
public static void main(String args[]) {
Maybe<Integer> five = new Maybe<Integer>(5);
Maybe<Integer> nope = new Maybe<Integer>(null);
Func<Integer, Monad<Integer>> addTwo = Monad.lift(new Add().apply(2));
Func<Integer, Monad<Void>> print = Monad.lift(new Func<Integer, Void>() {
@Override
public Void apply(Integer arg) {
System.out.println(arg.toString());
return null;
}
});
five.bind(addTwo).bind(print);
nope.bind(addTwo).bind(print);
}
}
// This program should print out "5" eight times and then exit
class Tester2 {
public static void main(String args[]) {
Func<Integer, Func<Integer, Integer>> addA = new Add();
Func2<Integer, Integer, Integer> addB = new Add();
Add addC = new Add();
System.out.println(addA.apply(2).apply(3));
System.out.println(((Func2<Integer, Integer, Integer>) addA).apply(2, 3));
System.out.println(((Add) addA).apply(2, 3));
System.out.println(addB.apply(2).apply(3));
System.out.println(addB.apply(2, 3));
System.out.println(((Add) addB).apply(2, 3));
System.out.println(addC.apply(2).apply(3));
System.out.println(addC.apply(2, 3));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment