/**
* Various iteration strategies.
*/
module strategy/iteration
imports strategy/conditional
strategies
/**
* Repeatedly apply s until it fails.
*/
repeat(s) =
try(s; repeat(s))
/**
* Repeatedly apply s until it fails and terminate with application of c.
*/
repeat(s, c) =
(s; repeat(s, c)) <+ c
/**
* Repeatedly apply s (at least once) and terminate with application of c.
*/
repeat1(s, c) =
s; (repeat1(s, c) <+ c)
/**
* Repeatedly apply s (at least once).
*/
repeat1(s) =
repeat1(s, id)
/**
* Repeatedly apply s until c succeeds.
*/
repeat-until(s, c) =
s; (c <+ repeat-until(s, c))
/**
* Applies s repeatedly exactly n times. If s fails at some point during
* the n applications, the entire strategy fails. The result of the
* strategy is that of the nth application of s.
*/
repeat(s | n) =
if <eq>(n, 0)
then
id
else
s; repeat(s|<dec>n)
end
/**
* While c succeeds apply s.
*/
while(c, s) =
try(c; s; while(c, s))
/**
* While c does not succeed apply s.
*/
while-not(c, s) =
c <+ (s; while-not(c, s))
/**
* Apply s at least once and then repeat while c succeeds.
*/
do-while(s, c) =
s; while(c, s)
/**
* Repeat application of s after initialization with i
* while c fails.
*/
for(i, c, s) =
i; while-not(c, s)
/**
* Apply s for each integer from low to up (inclusive).
*/
for(s : Int * a -> a | low, up) =
if <leq>(low, up) then
s(|low)
; for(s | <inc>low, up)
end