Line Filters in Elm

A line filter is a common type of program that reads input, processes it, and then prints some derived result. grep and sed are common line filters.

Here’s an example line filter in Elm that writes a capitalized version of all input text. You can use this pattern to write your own Elm line filters.

module Main exposing (main)

import Browser
import Html exposing (Html, div, text)
import Task
import Process


type Msg
    = GotLine String
    | Done


type alias Model =
    { lines : List String
    }


init : () -> ( Model, Cmd Msg )
init _ =
    ( { lines = [] }
    , Task.perform GotLine (Process.sleep 0 |> Task.andThen (\_ -> readLine))
    )


readLine : Task.Task String String
readLine =
    Task.succeed "" -- In a real scenario, this would read from stdin


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        GotLine line ->
            if line == "" then
                ( model, Task.perform (\_ -> Done) (Task.succeed ()) )
            else
                ( { model | lines = String.toUpper line :: model.lines }
                , Task.perform GotLine (Process.sleep 0 |> Task.andThen (\_ -> readLine))
                )

        Done ->
            ( model, Cmd.none )


view : Model -> Html Msg
view model =
    div [] (List.map (\line -> div [] [ text line ]) (List.reverse model.lines))


main : Program () Model Msg
main =
    Browser.element
        { init = init
        , update = update
        , view = view
        , subscriptions = \_ -> Sub.none
        }

In this Elm program:

  1. We define a Model that holds a list of processed lines.

  2. The init function sets up the initial model and kicks off the line reading process.

  3. The readLine function is a placeholder. In a real scenario, this would read from stdin.

  4. The update function processes each line as it’s read, converting it to uppercase and adding it to the model.

  5. The view function displays all processed lines.

  6. The main function sets up the Elm application.

To try out this line filter, you would need to set up an Elm application and provide input through some means (like a text area in a web page). Elm, being primarily a language for web applications, doesn’t have direct access to stdin like command-line programs do.

In a web context, you might use this filter like this:

  1. Create a text area for input.
  2. As the user types or pastes text, send each line to the Elm application.
  3. The Elm application processes each line and updates the view with the uppercase version.

This example demonstrates how to process text line by line in Elm, even though the exact mechanism of input and output differs from a command-line program.