(* * This file is a collection of functions to do an assortment of * imperative-style loops. See 501 lecture notes for further * discussion. Also, the following individual files contain looping * examples and further discussion: for.ml, while.ml, loops-tests.ml. *) structure Loops = struct exception EmptyLoop and ExitLoop (* * General purpose for-loop, returning the value of of the loop vars as of the * last iteration. If no iterations occur, EmptyLoop is raised to the caller. *) fun for(start:int, until, by, vars:'v, body:int*'v->'v): 'v = if start>until then raise EmptyLoop else let val result = body(start, vars) in for(start+by, until, by, result, body) handle EmptyLoop => result end (* * A la for, but returns list of all loop iterations. If no iterations, nil * is returned (hence, no exception need be raised). *) fun forl(start:int, until, by, vars:'v, body:int*'v->'v): 'v list = if start>until then [] else let val result = body(start, vars) in forl(start+by, until, by, result, body) @ [result] end; (* * C-Shell-style list iterator. *) fun foreach(l:'x list, vars:'y, body:'x*'y->'y):'y = if null(l) then raise EmptyLoop else let val result = body(hd(l), vars) in foreach(tl(l), result, body) handle EmptyLoop => result end (* * A la foreach, but returns list of all iteration results. *) fun foreachl(l:'x list, vars:'y, body:'x*'y->'y):'y list = if null(l) then [] else let val result = body(hd(l), vars) in foreachl(tl(l), result, body) @ [result] end (* * General-purpose while loop, returning list of body iterations. It's named * while1, since "while" is an SML keyword. *) fun while1(test:'x->bool, vars:'x, body:'x->'x): ('x) list = if test(vars) then let val result = body(vars) in while1(test, result, body) @ [result] end else [] fun loop(vars, body) = let val vars = body(vars) in loop(vars, body) end end (* structure Loops *)