package com.acme.symbolic; import church.lang.ByteStream; import church.lang.operators.Streams.$$encode; import church.primitives.Integers; import church.primitives.Objects; import static church.lang.operators.Streams.output; import static com.acme.symbolic.Expr.*; import static com.acme.symbolic.Primitive.*; @SuppressWarnings("unchecked") public class ExprTest { private static final $$encode<ByteStream, String> $S0 = Objects::$encode; private static final $$encode<ByteStream, Integer> $S1 = Integers::$encode; private static final $$encode<ByteStream, Primitive> $S2 = Primitive.$encode($S1, $S0); private static final $$encode<ByteStream, Expr> $S3 = Expr.$encode($S0, $S2); public static ByteStream test(Expr input) { return $S0.$encode($S2.$encode($S0.$encode($S3.$encode(output, input), " = "), eval(input)), "\n"); } public static void main(String[] args) { Expr zero = lambda("f", lambda("x", var("x"))); Expr one = lambda("x", var("x")); Expr two = lambda("f", lambda("x", app(var("f"), app(var("f"), var("x"))))); Expr i_0 = $const(integer(0)); Expr i_succ = $const(proc(arg -> new Primitive.Visitor<Primitive>() { public Primitive integer(int i) { return Primitive.integer((i + 1)); } } .get(arg))); test(app(app(app(two, two), i_succ), i_0)); test(app(app(app(two, app(two, two)), i_succ), i_0)); test(app(app(app(app(app(two, two), two), two), i_succ), i_0)); } }