Skip to content
AgileLogics
4 min read

Input and Command-Line Arguments

Prerequisites: Options: no more null

Reading from the keyboard

System.Console.ReadLine() reads one line of text typed by the user:

// illustrative: waits for keyboard input
open System

printf "What's your name? "
let name = Console.ReadLine()

printf "How old are you? "
match Int32.TryParse(Console.ReadLine()) with
| true, age -> printfn "Hi %s, next year you'll be %d." name (age + 1)
| false, _ -> printfn "Hi %s, that doesn't look like a number." name

A typical session:

What's your name? Ada
How old are you? 36
Hi Ada, next year you'll be 37.
  • open System lets you write Console instead of System.Console.
  • Input is always a string: parse it with TryParse and handle bad input instead of crashing.

Arguments in a script

Arguments after the script name are in fsi.CommandLineArgs. The first element is the script's own name:

// illustrative: run as  dotnet fsi greet.fsx Ada Grace
let args = fsi.CommandLineArgs |> Array.skip 1

if args.Length = 0 then
    printfn "Usage: dotnet fsi greet.fsx NAME..."
else
    for name in args do
        printfn "Hello, %s!" name
Hello, Ada!
Hello, Grace!

Arguments in a project

In a console project, the entry point receives the arguments. Mark the last function in the last file with [<EntryPoint>]; it returns an exit code (0 means success):

// illustrative: Program.fs, run as  dotnet run -- 3 4
[<EntryPoint>]
let main argv =
    match argv with
    | [| a; b |] ->
        printfn "%d" (int a + int b)
        0
    | _ ->
        eprintfn "Usage: add A B"
        1
7

Everything after -- in dotnet run -- ... is passed to your program. eprintfn writes to the error stream, which is where usage and error messages belong.

For real command-line tools, the Argu library parses options and generates help text from a discriminated union.