(*
 * This file contains definitions of the same for-loop functions defined in
 * for.ml.  Here, as many type declartions as possible are omitted to test the
 * smarts of the ML type inferencer.  The result -- only one integer decl is
 * required, to help the inferencer resolve the overloading of < and + to
 * integers.
 *)
structure ForLoops = struct
    exception EmptyLoop;

    (*
     * General purpose for-loop, returning a list of all loop iterations.
     *)
    fun for(start:int, until, by, vars, body) =
	if start>until then []
	else let val result = body(start, vars)
	     in for(start+by, until, by, result, body) @ [result] end;

    (*
     * A la for, but returns only the result of the last interation.
     *)
    fun for1(start, until, by, body, bodyin) =
	hd(for(start, until, by, body, bodyin))
	    handle Hd => raise EmptyLoop;

    (*
     * C-Shell-style list iterator.
     *)
    local
	fun foreach1(l, vars, body) =
	    if null(l) then []
	    else let val result = body(hd(l), vars)
		 in foreach1(tl(l), result, body) @ [result] end
    in
	fun foreach(l, vars, body) =
	    hd(foreach1(l, vars, body))
		handle Hd => raise EmptyLoop
    end
end;