Skip to content

Instantly share code, notes, and snippets.

@jbgi
Created June 8, 2016 15:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jbgi/2d26c2b30b658ea84b3e458cc8e846aa to your computer and use it in GitHub Desktop.
Save jbgi/2d26c2b30b658ea84b3e458cc8e846aa to your computer and use it in GitHub Desktop.
OCaml mimicry in Java translated to derive4j
// The file BoolExprs is generated by derive4j via the @Data annotation.
import static BoolExprs.*;
import java.util.function.Function;
import org.derive4j.Data;
@Data
interface BoolExpr<E> {
interface Cases<E, T> {
T True();
T False();
T And(BoolExpr<E> x, BoolExpr<E> y);
T Or(BoolExpr<E> x, BoolExpr<E> y);
T Not(BoolExpr<E> x);
T Base(E e);
}
<T> T match(Cases<E, T> arg);
static <E> Boolean eval(Function<E, Boolean> eval_base, BoolExpr<E> expr) {
Function<BoolExpr<E>, Boolean> eval_ = e -> eval(eval_base, e);
return BoolExprs.<E>cases()
.True(true)
.False(false)
.And((x, y) -> eval_.apply(x) && eval_.apply(y))
.Or((x, y) -> eval_.apply(x) || eval_.apply(y))
.Not(x -> !eval_.apply(x))
.Base(eval_base)
.apply(expr);
}
// But why be explicit about the recursion if derive4j generate the catamorphism for us? ;-)
static <E> Boolean evalViaCata(Function<E, Boolean> eval_base, BoolExpr<E> expr) {
return BoolExprs.cata(
() -> true,
() -> false,
(x, y) -> x.get() && x.get(),
(x, y) -> x.get() || x.get(),
(x) -> !x.get(),
eval_base
).apply(expr);
}
static void main(String[] args) {
BoolExpr<Integer> myExpression = Or(True(), Not(False()));
Function<Integer, Boolean> evalBase = f -> !(f==0);
Boolean result = eval(evalBase, myExpression);
Boolean resultViaCata = evalViaCata(evalBase, myExpression);
System.out.println(result); // true
System.out.println(resultViaCata); // true
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment