I have such a function:
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 while
statement, I cannot use break, because as you know, break
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 whether this solution suits with my problem.
Sadly F# does not support break
. There are various fairly complicated ways to deal with this (like this recent one or my computation builder), but those have disadvantages and make your code fairly complex.
The general way to deal with this is to rewrite the code using recursion - this will typically compile to the same IL as what you would write in C# using break
and continue
.
So, the while
block in your snippet could be written as a function that calls itself recursively until the result is not "ERR" and then returns the 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()
Aside, I also changed your match
on Booleans into an ordinary if
- when you have just two cases and they are Booleans, there is really no point in using match
over if
.
Also, I kept your mutable variable c
, but I suspect that you no longer need it thanks to recursion.
Break does not exist in F#, personally I would try to avoid breaks even in C# as there are many alternative/cleaner ways to break a loop.
A simple fix while keeping your imperative code style will be this:
c <- ScanColor()
while (c = "ERR") do
CalibrateSensorPosition()
c <- ScanColor()
ResetSensorPosition()
But in F# it can be further compacted to this one-liner:
while (c <- ScanColor(); c = "ERR") do CalibrateSensorPosition()
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()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With