Avoid variable state booleans

Suppose that before you introduce a lengthy process, you need to perform some checks before starting.

Suppose also that after these checks are completed, you do not need to perform the checks again (perhaps many of these checks are also relatively expensive to complete).

How can you avoid the condition here?

More generally, in Python, you could have something like a generator or coroutine that could hold these checks and state. Is there a good way for F-sharpy to get rid of volatile logic elements to indicate a missed check of all checks performed?

let r = new System.Random()

let someCondition1 () = 
    r.Next() % 523452321 = 0 

let someCondition2 () = 
    r.Next() % 243142321 = 0 

let mutable conditionCheck1 = false
let mutable conditionCheck2 = false
let rec conditionChecks () =

    match conditionCheck1 with
    | true -> ()
    | false -> match someCondition1 () with
               | false -> conditionChecks ()
               | true  -> conditionCheck1 <- true // never check again

    match conditionCheck2 with
    | true -> ()
    | false -> match someCondition2 () with
               | false -> conditionChecks ()
               | true  -> conditionCheck2 <- true // never check again

let rec eventLoop () =
    eventLoop ()

conditionChecks ()
eventLoop ()
+4
source share
2 answers

, conditionChecks false. , :

  • .
  • , . ( , ).
  • .

, - async. async , , true. . : , , .

let r = new System.Random()

let rec someCondition1 () =
    async {
        // if r.Next() % 523452321 = 0 then
        printfn "Checking condition 1"
        if r.Next() % 52 = 0 then  // So our output is shorter
            return true
        else
            return! someCondition1 ()
    }

let rec someCondition2 () = 
    async {
        // if r.Next() % 243142321 = 0 then
        printfn "Checking condition 2"
        if r.Next() % 24 = 0 then  // So our output is shorter
            return true
        else
            return! someCondition2 ()
    }

let allConditions = [
    someCondition1 ()
    someCondition2 ()
]

let rec eventLoop () =
    printfn "Event loop runs now"
    // eventLoop ()  // Disabled so our test run will not infiloop

let ready = allConditions |> Async.Parallel |> Async.RunSynchronously
if Array.reduce (&&) ready then
    eventLoop()
else
    printfn "Some conditions returned false somehow"

, , :

Checking condition 1
Checking condition 1
Checking condition 1
Checking condition 1
Checking condition 1
Checking condition 1
Checking condition 1
Checking condition 1
Checking condition 1
Checking condition 2
Checking condition 2
Checking condition 1
Checking condition 2
Checking condition 1
Checking condition 2
Checking condition 1
Checking condition 1
Checking condition 1
Checking condition 1
Checking condition 1
Checking condition 1
Checking condition 1
Checking condition 1
Checking condition 1
Checking condition 1
Checking condition 1
Checking condition 1
Checking condition 1
Checking condition 1
Event loop runs now

, 2 true - 1 , true. true, .

, , , "" . - , , false, . :

let condition1CanNeverBeTrue () =
    r.Next() % 123456789 = 0

let rec someCondition1 () =
    async {
        if r.Next() % 523452321 = 0 then
            return true
        else
            if condition1CanNeverBeTrue() then
                return false
            else
                return! someCondition1 ()
    }

, .

, , , let ready = ... :

let ready = allConditions |> List.map Async.RunSynchronously

, , List.reduce Array.reduce .

+6

, .

, , .

+2

Source: https://habr.com/ru/post/1650247/


All Articles