(*do*) (* Functional implementation of the WHILE and DO-FOR constructs of procedural languages. An example is given of the use of both, that is implementation of a psuedo-iterative factorial *) fun do_while test body s = if test s then do_while test body (body s) else s; fun while_fact n = let val (_,r) = do_while (fn s => let val (x,_) = s in x<=n end) (fn s => let val (x,y) = s in (x+1,x*y) end) (1,1) in r end; fun do_for n body s = if n>0 then do_for (n-1) body (body s) else s; fun do_fact n = let val (_,r) = do_for n (fn s => let val (x,y) = s in (x+1,x*y) end) (1,1) in r end; fun fact 0 = 1 |fact n = n * fact (n-1); (* Assume we have 2 lists x = [1,2,3,4], y = [5,6,7] Deliver [(1*5 + 1*6 + 1*7),(2*5 + 2*6 + 3*6), .... (4*5 + 4*6 + 4*7)] In a "pascal-like" language we might have the following: result := []; while x isnt empty do begin sum := 0; i := hd(x); x := tl(x); y' := y; while y' isnt empty do begin j := hd(y'); y' := tl(y'); sum := sum + i*j end; result := result @ [sum] end; We will implement this in ml using do_while *) fun do_y ((sum:int),(i:int),[]) = (sum,i,[]) |do_y ((sum:int),(i:int),((j:int)::y)) = (sum + (i*j),i,y); fun test_y (_,_,y) = not (null y); fun do_x (result,[],y) = (result,[],y) |do_x (result,((i:int)::x),y) = let val (sum,_,_) = do_while test_y do_y (0,i,y) in (result @ [sum],x,y) end; fun test_x (_,x,_) = not (null x); fun vector_product x y = let val (result,_,_) = do_while test_x do_x ([],x,y) in result end;