module ListRev2;
data Closure = Lam1(Closure, Closure) | Lam2 | Lam3(A);
// let rec apply c a = match c with
// Lam1(f,g) -> apply f (apply g a) | Lam2 -> a | Lam3(x) -> x :: a ;;
def List apply(Closure c, List a) =
case c {
Lam1(f,g) => apply(f, apply(g,a));
Lam2 => a;
Lam3(x) => Cons(x,a);
};
def Closure comp(Closure f, Closure g) = Lam1(f,g);
// let rev2 l =
// let rec walk = function
// | [] -> Lam2
// | x :: xs -> comp (walk xs) (Lam3 x)
// in
// apply (walk l) [];;
def Closure walk(List l) =
case l {
Nil => Lam2;
Cons(x,xs) => comp(walk(xs),Lam3(x));
};
def List rev2(List l) = apply(walk(l), Nil);
def List start(List l) = rev2(l);
{
}