F # break from while loop in complex statements

I have a function like this:

let ScanColors() =
    for i in 1..54 do
        let mutable c = Unchecked.defaultof<string>

        if (i = 9) then 
            c <- "U - WHITE"
        else
            if (i <> 0 && i%9 = 0) then 
                MoveSensor(SensorPos.THIRD)
            else
                MoveSensor(
                    match ((i - (i/9)*9)%2 <> 0) with 
                        | true -> SensorPos.SECOND
                        | false -> SensorPos.FIRST)

            while (true) do
                c <- ScanColor()
                if (c = "ERR") then
                    CalibrateSensorPosition()
                else
                   break
            ResetSensorPosition()

      

in this function, in the statement while

, I cannot use break because, as you know, break

it is not used in F #. I was looking for alternatives for break

and I saw this link:

F # break from while loop

But to be honest, I couldn't be sure if this solution is the right solution for my problem.

+3


source to share


4 answers


Sadly, F # doesn't support break

. There are various fairly sophisticated ways to deal with this (like this recent one or my compute builder ), but these have drawbacks and make your code quite complex.

The general way to deal with this is to rewrite the code using recursion - this will usually compile with the same IL as in C # using break

and continue

.

So, a block while

in your snippet can be written as a function that calls itself recursively until the result is "ERR" and then returns c

:

let rec scanWhileErr () =     
  let c = ScanColor()
  if c = "ERR" then
    CalibrateSensorPosition()
    scanWhileErr()
  else c

      



And then call this function from the main block:

if (i <> 0 && i%9 = 0) then 
  MoveSensor(SensorPos.THIRD)
else
  MoveSensor(if (i - (i/9)*9)%2 <> 0 then SensorPos.SECOND else SensorPos.FIRST)

c <- scanWhileErr ()
ResetSensorPosition()

      

Also, I also changed yours match

to Booleans to normal if

- when you only have two cases and they are booleans, there is no point in using match

over if

.

Also, I saved your mutable variable c

, but I suspect you don't need it anymore thanks to recursion.

+7


source


Break does not exist in F #, personally I will try to avoid breaks even in C # as there are many alternative / clean ways to break the loop.

A simple fix, keeping your imperative coding style, would be:

c <- ScanColor()
while (c = "ERR") do
    CalibrateSensorPosition()
    c <- ScanColor()
ResetSensorPosition()

      



But in F # it can be further compressed into this one-liner:

while (c <- ScanColor(); c = "ERR") do CalibrateSensorPosition()

      

+5


source


Actually, I think this approach is fine and worked in my case:

        let mutable flag = true
        while (flag = true) do
            c <- ScanColor()
            if (c = "ERR") then
                CalibrateSensorPosition()
            else
               flag <- false
        ResetSensorPosition()

      

+1


source


I think the easy way is when you need to have a "break" in the loop, then you just make sure the loop is complete.

an example of this would be if we have a while loop that looks like this:

while i < upperlimit do
   if a
   then break

      

0


source







All Articles