Functions that resemble imperative syntax
A twist on the classic while loop. It loops while the condition is NOT met.
countJustForFun : Int -> Int
countJustForFun to =
Loop.until
((==) to)
0
((+) 1)Much like while, however this function applies its a -> a before it continues, ensuring that f is applied to the output at least once.
while ((>) 0) 0 ((+) 1) == 0
doWhile ((>) 0) 0 ((+) 1) == 1A way that a loop can end
A loop in imperative code might have break and continue cases that are clearly marketed out with words like break; and return ...;. With this explicitLoop function you can map the break points in imperative code directly to Break and Continue points in a function.
clipSegment x0 y0 x1 y1 c0 c1 ({ xmax, xmin, ymax, ymin } as viewport) =
Imperative.explicitLoop
(\{ x0, y0, x1, y1, c0, c1 } ->
if c0 == 0 && c1 == 0 then
Imperative.Break <| Just ( x0, y0, x1, y1 )
else if Bitwise.and c0 c1 /= 0 then
Imperative.Break Nothing
else
let
c =
if c0 == 0 then
c1
else
c0
( x, y ) =
if Bitwise.and c 8 /= 0 then
( x0 + (x1 - x0) * (ymax - y0) / (y1 - y0), ymax )
else if Bitwise.and c 4 /= 0 then
( x0 + (x1 - x0) * (ymin - y0) / (y1 - y0), ymin )
else if Bitwise.and c 2 /= 0 then
( xmax, y0 + (y1 - y0) * (xmax - x0) / (x1 - x0) )
else
( xmin, y0 + (y1 - y0) * (xmin - x0) / (x1 - x0) )
in
if c0 /= 0 then
Imperative.Continue { x0 = x, y0 = y, x1 = x1, y1 = y1, c0 = regionCode x y viewport, c1 = c1 }
else
Imperative.Continue { x0 = x0, y0 = y0, x1 = x, y1 = y, c1 = regionCode x y viewport, c0 = c0 }
)
{ x0 = x0, y0 = y0, x1 = x1, y1 = y1, c1 = c1, c0 = c0 }
The classic while loop.