I have been trying to re-write one of my simple C# console app into purely functional F# code (if at all possible). Up until now I have managed to re-write while blocks into "immutable" F# with the help of Seq (something like Seq.initInfinite sequenceGenerator |> Seq.takeWhile condition |> Seq.iter bodyOfWhileCycle) - the website "F# for Fun and Profit" has been my inspiration.
However, this time I came across a simple while block that in "mutable" F# looks like follows (and it works):
printfn "Type low OP number"
let mutable lowLimit = parseMe (Console.ReadLine())
printfn "Type high OP number"
let mutable highLimit = parseMe (Console.ReadLine())
let mutable myCondition = true
if highLimit > lowLimit then myCondition <- false
while myCondition do
printfn "Type low OP number again"
lowLimit <- parseMe (Console.ReadLine())
printfn "Type high OP number again"
highLimit <- parseMe (Console.ReadLine())
if highLimit > lowLimit then myCondition <- false
Can anyone help me to figure out how to refactor this "mutable" while-do block into a functional style? My attempts to refactor it do not work the way I want - I do not know how to get the lowLimit1/highLimit1 values out of the bodyOfWhileCycle function. One of my unsuccessfull attempts is here:
printfn "Type low OP number"
let lowLimit = parseMe (Console.ReadLine())
printfn "Type high OP number"
let highLimit = parseMe (Console.ReadLine())
let verifyingInputValues: unit =
let bodyOfWhileCycle _=
printfn "Type low OP number again"
let lowLimit1 = parseMe (Console.ReadLine())
printfn "Type high OP number again"
let highLimit1 = parseMe (Console.ReadLine())
()
fun _ -> highLimit - lowLimit
|> Seq.initInfinite
|> Seq.takeWhile ((>) 0)
|> Seq.iter bodyOfWhileCycle
verifyingInputValues
It looks like you want to have the while loop finish when highLimit > lowLimit and otherwise repeat requests, and presumably, do something with them later.
In which case you want a function that returns a tuple of ( highLimit, lowLimit ) and not unit (). A recursive function can handle the apparent change in state or IO between calls, without mutability, by passing the new state in as an argument.
let fullParse: () -> int *int =
let parseHighLow again =
printfn "Type low OP number %s" again
let lowLimit = parseMe (Console.ReadLine())
printfn "Type high OP number %s" again
let highLimit = parseMe (Console.ReadLine())
highLimit, lowLimit
let rec verify (high, low) =
if high > low then high, low else verify (parseHighLow "again")
verify (parseHighLow "")
let (high, low) = fullParse ()
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