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:
But to be honest, I couldn't be sure if this solution is the right solution for my problem.
source to share
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.
source to share
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()
source to share