Line Filters in Standard ML

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 Standard ML that writes a capitalized version of all input text. You can use this pattern to write your own Standard ML line filters.

fun main () =
    let
        (* Read input line by line *)
        fun readLines () =
            case TextIO.inputLine TextIO.stdIn of
                SOME line => line :: readLines ()
              | NONE => []

        (* Process each line *)
        fun processLine line =
            String.map Char.toUpper line

        (* Write processed lines to stdout *)
        fun writeLines lines =
            List.app (fn line => TextIO.print (processLine line)) lines

        val inputLines = readLines ()
    in
        writeLines inputLines;
        OS.Process.exit OS.Process.success
    end

val _ = main ()

In this Standard ML version:

  1. We define a main function that encapsulates our program logic.

  2. The readLines function reads input lines from TextIO.stdIn (standard input) until end-of-file is reached, accumulating them in a list.

  3. The processLine function takes a line and converts it to uppercase using String.map and Char.toUpper.

  4. The writeLines function takes the list of input lines, processes each one, and prints the result to stdout.

  5. We call these functions in sequence in the main function.

  6. Finally, we call main () to execute our program.

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. Assuming you’ve saved the Standard ML code in a file named line-filter.sml:

$ cat /tmp/lines | sml line-filter.sml
HELLO
FILTER

Note that the exact command to run a Standard ML program may vary depending on your Standard ML implementation. The above example assumes you’re using Standard ML of New Jersey (SML/NJ).

This Standard ML version provides similar functionality to the original Go program, reading lines from standard input, converting them to uppercase, and printing the results to standard output.