I desperately want to create great and useful programs for myself and others. I am focused on F# and eventually Azure. I want to focus on the “mechanics” of the program first. In doing so, I want to create a super simple “UI”, a basic “do this” and show me the result. Then let me “do that” and show me the result. A console app seems best to me.
Does the following seem to be a good start? Suggestions?
GIST
open System
let printPrompt () =
printf "command:>"
let getCommandLineInput _ =
printPrompt ()
System.Console.ReadLine ()
let writeError value =
printfn "ERROR - No Match\nYou typed: %s" value
let writeMatch value =
printfn "Matched: %s" value
let processCommandLineInput commandLineInput =
match commandLineInput with
| "a" -> writeMatch "a"
| "b" -> writeMatch "b"
| "exit" -> Environment.Exit 55
| "quit" -> Environment.Exit 55
| _ -> writeError commandLineInput
//change to output a 'command'?
let progLoop () =
let commandLineInput = Seq.initInfinite getCommandLineInput
Seq.iter processCommandLineInput commandLineInput
[<EntryPoint>]
let main argv =
progLoop ()
0
- You probably might consider option to change color of the message depending on its type (Error, General, Success).
Console.BackgroundColor
- In case when you have exactly the same action that performed by different patterns (“quit”, “exit”) you can combine them via “|”
| "a" | "b" as v -> writeMatch v
| "exit" | "quit" -> Environment.Exit 55
- You can use pipe-forward operator inside of the
progLoop
:
let progLoop () =
getCommandLineInput
|> Seq.initInfinite
|> Seq.iter processCommandLineInput
Thank you.
- The colors is a great idea, that is more fluff than I am willing to invest at this stage I would expect that to be a future upgrade though.
- This is really helpful. I actually had tried
"exit" || "quit"
and of course that didn’t work. Now I see the correct way. TY.
- Seeing this and being able to compare it gives me great insight. Again. Thank you.
I updated the GIST
So given the updated program:
//Very basic F# command line UI
//trying to get a global state
open System
let mutable x = "NoUser"
let printPrompt () =
printfn "Current State: %s" x
printf "command:>"
let getCommandLineInput _ =
printPrompt ()
System.Console.ReadLine ()
let writeError value =
printfn "ERROR - No Match\nYou typed: %s" value
let writeMatch value =
printfn "Matched: %s" value
let processCommandLineInput commandLineInput =
match commandLineInput with
| "a" -> writeMatch "a"; x <- "Ivan"
| "b" -> writeMatch "b"; x <- "Bob"
| "c" -> writeMatch "b"
| "exit" | "quit" -> Environment.Exit 55
| _ -> writeError commandLineInput
//change to output a 'command'?
//let progLoop () =
// let commandLineInput = Seq.initInfinite getCommandLineInput
// Seq.iter processCommandLineInput commandLineInput
let progLoop () =
getCommandLineInput
|> Seq.initInfinite
|> Seq.iter processCommandLineInput
[<EntryPoint>]
let main argv =
progLoop ()
0
I am stuck on updating state without the mutable. My thought is I need to pass the current state through the interactions, but I am not getting it figured out. So the process would be program starts, initial state is set. If I do a particular function, it can create a new state (updated) state and pass it along as the new current state for the next iteration. This is like the Elmish idea. I am just not seeing where to pass and pickup the state in each iteration. Any suggestions?
Then I suppose it would be easier to use simple recursive function.
open System
let printPrompt state =
printfn "Current State: %s" state
printf "command:>"
let getCommandLineInput = Console.ReadLine
let writeError value =
printfn "ERROR - No Match\nYou typed: %s" value
let writeMatch value =
printfn "Matched: %s" value
let processCommandLineInput state commandLineInput =
match commandLineInput with
| "a" -> writeMatch "a"; Some "Ivan"
| "b" -> writeMatch "b"; Some "Bob"
| "c" -> writeMatch "c"; Some state
| "exit" | "quit" -> None
| _ -> writeError commandLineInput; Some state
let rec progLoop state =
state |> printPrompt
let updated =
getCommandLineInput()
|> processCommandLineInput state
match updated with
| Some newState -> progLoop newState
| None -> Environment.Exit 55
[<EntryPoint>]
let main argv =
"NoUser" |> progLoop
0