Often when learning a new technology I start with a simple console application in which the program is run in a loop it continues to prompt you for more input until you give some command like quit or exit or whatever you choose:
Enter input: someInputsomeOutputEnter input: otherInputsomeoutPutEnter input: quitThanks! Come again!
Enter input: someInput
Enter input: otherInput
Enter input: quit
Thanks! Come again!
The code for this is in an imperative language is usually something like:
3: Console.Write("\nEnter input:");
4: var line = Console.ReadLine();
5: if(line == "quit") break;
10: Console.WriteLine("Thanks! Come Again");
While reading some F# samples, I saw some code doing essentially the same thing which looked something like:
1: Console.Write "\nEnter input:"
2: let mutable input = Console.ReadLine()
3: while input <> "quit"
6: if input <> "quit"
8: doSomething input
9: Console.Write "\nEnter input:"
10: input <- Console.ReadLine()
Now this just feels dirty! In a functional language explicit loop constructs like a while loop feel wrong. I different way of doing this which is more functional is to create an infinite list of actions. Where each action represents one iteration of any of the above loops. Then you just execute each action until some condition is met (like seeing the input “quit”).
1: let action = fun _ ->
2: Console.Write "\nEnter input: "
5: let readlines = Seq.init_infinite (fun _ -> action())
7: let run item = if item = "quit"
8: then Some(item)
10: parse item
13: Seq.first run readlines |> ignore
14: Console.WriteLine "Thanks! Come Again"
This code makes use of the Seq.init_infinite which create a infinite sequence and Seq.first which enumerates the sequence until the passed in function returns Some.