Tickers in Elm

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


type Msg
    = Tick Time.Posix
    | Stop


type alias Model =
    { ticks : Int
    }


init : () -> ( Model, Cmd Msg )
init _ =
    ( { ticks = 0 }
    , Cmd.none
    )


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        Tick _ ->
            ( { model | ticks = model.ticks + 1 }
            , if model.ticks >= 3 then
                Task.perform (\_ -> Stop) (Task.succeed ())
              else
                Cmd.none
            )

        Stop ->
            ( model, Cmd.none )


subscriptions : Model -> Sub Msg
subscriptions _ =
    Time.every 500 Tick


view : Model -> Html Msg
view model =
    div []
        [ text <| "Ticks: " ++ String.fromInt model.ticks
        ]


main : Program () Model Msg
main =
    Browser.element
        { init = init
        , update = update
        , subscriptions = subscriptions
        , view = view
        }

This Elm program demonstrates the concept of tickers, which are used to perform actions at regular intervals. Here’s how it works:

  1. We define a Model that keeps track of the number of ticks.

  2. The Msg type defines two types of messages: Tick for each interval and Stop to end the ticker.

  3. In the update function, we handle these messages:

    • On each Tick, we increment the tick count.
    • If we’ve reached 3 ticks, we send a Stop message.
  4. The subscriptions function sets up a subscription that sends a Tick message every 500 milliseconds.

  5. The view function simply displays the current number of ticks.

  6. In the main function, we set up the Elm application using Browser.element.

When you run this program, you should see the tick count increase three times before it stops.

This example demonstrates how to use Elm’s built-in Time module to create a ticker-like behavior. While Elm doesn’t have the exact equivalent of Go’s ticker, this approach achieves a similar result in a functional, reactive style that’s idiomatic to Elm.

Note that in Elm, we don’t explicitly stop the ticker. Instead, we use the subscriptions function to control when the ticker is active. In this case, we could modify the subscriptions function to return Sub.none after receiving the Stop message, effectively stopping the ticker.