Line Filters in F#
A line filter is a common type of program that reads input on stdin, processes it, and then prints some derived result to stdout. grep
and sed
are common line filters.
Here’s an example line filter in F# that writes a capitalized version of all input text. You can use this pattern to write your own F# line filters.
open System
open System.IO
[<EntryPoint>]
let main argv =
// Read input from stdin line by line
use reader = new StreamReader(Console.OpenStandardInput())
// Process each line
while not reader.EndOfStream do
let line = reader.ReadLine()
let uppercaseLine = line.ToUpper()
// Write out the uppercased line
printfn "%s" uppercaseLine
// Check for errors during reading
match reader.BaseStream with
| :? FileStream as fs when fs.Length = 0L ->
eprintfn "error: No input provided"
1 // Exit with error code
| _ -> 0 // Exit successfully
In this F# version:
We use
System.IO.StreamReader
to read from standard input, which gives us a convenient way to read input line by line.We use a
while
loop to continue reading lines until we reach the end of the stream.For each line, we use the
ToUpper()
method to convert it to uppercase.We use
printfn
to write the uppercased line to standard output.After the loop, we check if there was any input at all. If not, we print an error message to standard error using
eprintfn
.The
main
function returns an integer, which serves as the exit code of the program (0 for success, non-zero for error).
To try out our line filter, first make a file with a few lowercase lines.
$ echo 'hello' > /tmp/lines
$ echo 'filter' >> /tmp/lines
Then use the line filter to get uppercase lines.
$ cat /tmp/lines | dotnet run
HELLO
FILTER
Note that to run this F# program, you need to have the .NET SDK installed and compile the program first. You would typically save this code in a file with a .fs
extension, create a project file, and then use dotnet run
to compile and run the program.