package no.java.incogito; import fj.F; import fj.P2; import fj.P; import fj.Bottom; import fj.data.List; /** * This really should be <code>Class<? extends A></code>. * @param <A> * @param <B> */ public class PatternMatcher<A, B> { private final List<P2<Class, F<A, B>>> matchers; PatternMatcher(List<P2<Class, F<A, B>>> matchers) { this.matchers = matchers; } public static <A, B> PatternMatcher<A, B> match() { return new PatternMatcher<A, B>(List.<P2<Class, F<A, B>>>nil()); } public PatternMatcher<A, B> add(Class klass, F<A, B> f) { return new PatternMatcher<A, B>(matchers.cons(P.p(klass, f))); } public B match(A a) { for (P2<Class, F<A, B>> matcher : matchers.reverse()) { if (matcher._1().isAssignableFrom(a.getClass())) { return matcher._2().f(a); } } throw Bottom.error("No match"); } }