Created
June 10, 2011 22:13
-
-
Save ahamid/1019897 to your computer and use it in GitHub Desktop.
Monad in Java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Created on Feb 7, 2009 | |
package snippet; | |
import java.math.BigDecimal; | |
public class Monad { | |
// this is our "side effect" ("amplified object") | |
public static class AnnotatedObject<T> { | |
public T o; | |
public String note; | |
} | |
public static <T> AnnotatedObject<T> performAnnotationSideEffect(T t, String note) { | |
AnnotatedObject<T> ao = new AnnotatedObject<T>(); | |
ao.o = t; | |
ao.note = note; | |
return ao; | |
} | |
public static interface IntegerToAnnotatedStringFunction { | |
public AnnotatedObject<String> invoke(Integer i); | |
} | |
public static class DefaultIntegerToAnnotatedStringFunction implements IntegerToAnnotatedStringFunction { | |
public AnnotatedObject<String> invoke(Integer i) { | |
AnnotatedObject<String> ao = performAnnotationSideEffect(i.toString(), "Converted integer " + i + " to string"); | |
return ao; | |
} | |
} | |
public static interface StringToAnnotatedBigDecimalFunction { | |
public AnnotatedObject<BigDecimal> invoke(String s); | |
} | |
public static class DefaultStringToAnnotatedBigDecimalFunction implements StringToAnnotatedBigDecimalFunction { | |
public AnnotatedObject<BigDecimal> invoke(String s) { | |
AnnotatedObject<BigDecimal> ao = performAnnotationSideEffect(new BigDecimal(s), "Converted string " + s + " to bigdecimal"); | |
return ao; | |
} | |
} | |
// now I want to compose the two functions to get Integer -> AnnotatedObject<BigDecimal> | |
public static interface IntegerToAnnotatedBigDecimalFunction { | |
public AnnotatedObject<BigDecimal> invoke(Integer i); | |
} | |
public static class Compose { | |
public IntegerToAnnotatedBigDecimalFunction invoke(final StringToAnnotatedBigDecimalFunction f, final IntegerToAnnotatedStringFunction g) { | |
return new IntegerToAnnotatedBigDecimalFunction() { | |
public AnnotatedObject<BigDecimal> invoke(Integer i) { | |
//return f.invoke(g.invoke(i)); // XXX type error, canna doit captin! | |
return null; | |
} | |
}; | |
} | |
} | |
// we need a function that takes an AnnotatedObject<String> and can produce a function String->AnnotatedObject<BigDecimal> | |
public static interface AnnotationMonad { | |
public IntegerToAnnotatedBigDecimalFunction BIND(AnnotatedObject<String> s, StringToAnnotatedBigDecimalFunction f); | |
} | |
public static class DefaultAnnotationMonad { | |
public IntegerToAnnotatedBigDecimalFunction BIND(final AnnotatedObject<String> s, final StringToAnnotatedBigDecimalFunction f) { | |
// in here we deal with combining "side-effects"! | |
// they are the same "type" of side effect, so we should be able to come up with a way to combine them (?) | |
return new IntegerToAnnotatedBigDecimalFunction() { | |
public AnnotatedObject<BigDecimal> invoke(Integer i) { | |
AnnotatedObject<BigDecimal> result = f.invoke(s.o); | |
result.note = s.note + result.note; // append to the previous note | |
return result; | |
} | |
}; | |
} | |
} | |
public static class ComposeWithMonads { | |
public IntegerToAnnotatedBigDecimalFunction invoke(final StringToAnnotatedBigDecimalFunction f, final IntegerToAnnotatedStringFunction g) { | |
return new IntegerToAnnotatedBigDecimalFunction() { | |
public AnnotatedObject<BigDecimal> invoke(Integer i) { | |
return new DefaultAnnotationMonad().BIND(g.invoke(i), f).invoke(i); | |
} | |
}; | |
} | |
} | |
public static void main(String[] args) { | |
Integer i = new Integer(100); | |
AnnotatedObject<BigDecimal> o = new ComposeWithMonads().invoke(new DefaultStringToAnnotatedBigDecimalFunction(), new DefaultIntegerToAnnotatedStringFunction()).invoke(i); | |
System.out.println(o.o); | |
System.out.println(o.note); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment