F# How do a create a loop in a console app that loops through a method until a certain key is hit

StackOverflow https://stackoverflow.com/questions/17989750

  •  04-06-2022
  •  | 
  •  

Question

I have C# console app with an infinite loop method that looks like this

while (true) 
{
    Event eventObj = session.NextEvent();               
    foreach (Message msg in eventObj)   
    {
        System.Console.WriteLine(msg.ToString());
    }
}

I have tried to port it to F# in this way, adding functionality that exits the loop if the "Q" key is pressed.

member private this.SynchronousRespsonse =
    let rec checkResponse = 
        let c = System.Console.ReadKey()
        if c.Key = System.ConsoleKey.Q then
                 this.unsubscibe
        else  
            let eventObj : Event = session.NextEvent()
            for msg in eventObj do
                printfn "%A" msg.ToString
     checkResponse

But it is not working. Console output is:

checking...
<fun:checkResonse@41-1>
Unsubscribing ...

How can I write the loop to accomplish the same as the C# one while adding a convenient way to exit the loop?

Edit: I'm looking for a way to have it loop checking for new events but stop if the "Q" key is pressed. I do not want it to wait for a key before looping again. So System.Console.ReadKey() is probably not the right choice.

Était-ce utile?

La solution

You need to actually define functions rather than just variables - you want something like

member private this.SynchronousRespsonse() =
        let c = System.Console.ReadKey()
        if c.Key = System.ConsoleKey.Q then
                 this.unsubscibe
        else  
            let eventObj : Event = session.NextEvent()
            for msg in eventObj do
                printfn "%A" msg.ToString
            this.SynchronusResponse()

Also, the extra rec binding is not required and you want the recursion to occur only in the else block so that you can return after Q is pressed

Autres conseils

Thanks to John Palmer's solution, the recursion/looping portion of function performed exactly as I wanted. To get the exact looping stopping behaviour I wanted (always loop unless "Q" key is pressed) required a little bit more massaging. Here is the final solution

member private this.SynchronousRespsonse =
    let eventObj : Event = session.NextEvent()
    for msg in eventObj do                    
        // to some stuff here  
    if Console.KeyAvailable && Console.ReadKey().Key = ConsoleKey.Q then
        this.unsubscibe
    else
        this.SynchronousRespsonse
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top