(*
 * This file contains the def of a generic stack datatype, with standard stack
 * operations to create, push, pop, top, and check if empty.
 *)
abstype 'elem stack =
    Empty |
    Body of 'elem list
with
    exception EmptyStack;

    val newStack = Empty;

    fun isEmpty(Empty) = true |
        isEmpty(Body(s):'elem stack) = false;

    fun push(Empty, e) = Body[e] |
        push(Body(s), e) = Body(e::s);

    fun pop(Empty) = Empty |
        pop(Body(nil)) = Empty |
        pop(Body(e::nil)) = Empty |
        pop(Body(e::es)) = Body(es);

    fun top(Empty) = raise EmptyStack |
        top(Body(s)) = hd(s);
end;