Prelude.STACKPurely functional stacks.
Basically, a set of functions that treat lists as stacks, and a private type to enhance type safety.
The hd of the list is the top of the stack.
Conversion between lists and stacks is essentially free, and you can coerce stacks to lists for pattern matching:
match ((empty |> push 1) :> int list) with [] -> ... val empty : 'a tThe empty stack.
val size : 'a t -> int(size s) is the number of items on the stack s.
val top : 'a t -> 'a option(top s) is the top item on stack s.
drop is (pop $ snd): it throws away the top item on s.
Invariant: (push x s |> drop) = s
(pop s) is (top s, drop s)
Invariants:
(pop empty) = (None, empty)(push x s |> pop) = (Some x,s)swap is Forth's SWAP.
Applying swap to the empty list or to a singleton list has no effect.
Invariants:
(push x empty |> swap |> pop) = (None, empty)(push x s |> push y |> swap |> pop) = (Some x, push y s)val fold : ('a -> 'b -> 'a) -> 'a -> 'b t -> 'a(fold f init t) folds f across the stack t with init as the initial accumulator.
val of_list : 'a list -> 'a t(of_list (x::[])) = (push x empty)
val to_list : 'a t -> 'a list(push 1 empty |> push 2 |> to_list) = [2;1]
val random : ?size:(unit -> int) -> (unit -> 'a) -> unit -> 'a t(random ?size r ()) is a random stack of size (size ()) (default: < 100), and each element is given by (r ()).