Embed Directive in Elm

Here’s the translation of the Go embed directive example to Elm, formatted in Markdown suitable for Hugo:

module Main exposing (main)

import Html exposing (Html, div, text)
import Http
import Task exposing (Task)


-- In Elm, we don't have a direct equivalent to Go's embed directive.
-- Instead, we'll simulate it by loading files at runtime.

type alias Model =
    { fileString : String
    , fileByte : String
    , file1Content : String
    , file2Content : String
    }


init : () -> ( Model, Cmd Msg )
init _ =
    ( { fileString = ""
      , fileByte = ""
      , file1Content = ""
      , file2Content = ""
      }
    , Cmd.batch
        [ loadFile "folder/single_file.txt" GotFileString
        , loadFile "folder/single_file.txt" GotFileByte
        , loadFile "folder/file1.hash" GotFile1Content
        , loadFile "folder/file2.hash" GotFile2Content
        ]
    )


type Msg
    = GotFileString (Result Http.Error String)
    | GotFileByte (Result Http.Error String)
    | GotFile1Content (Result Http.Error String)
    | GotFile2Content (Result Http.Error String)


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        GotFileString result ->
            ( { model | fileString = Result.withDefault "" result }, Cmd.none )

        GotFileByte result ->
            ( { model | fileByte = Result.withDefault "" result }, Cmd.none )

        GotFile1Content result ->
            ( { model | file1Content = Result.withDefault "" result }, Cmd.none )

        GotFile2Content result ->
            ( { model | file2Content = Result.withDefault "" result }, Cmd.none )


view : Model -> Html Msg
view model =
    div []
        [ text model.fileString
        , text model.fileByte
        , text model.file1Content
        , text model.file2Content
        ]


loadFile : String -> (Result Http.Error String -> Msg) -> Cmd Msg
loadFile filename msg =
    Http.get
        { url = filename
        , expect = Http.expectString msg
        }


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

In Elm, we don’t have a direct equivalent to Go’s embed directive, which allows embedding files at compile time. Instead, we simulate this behavior by loading files at runtime using HTTP requests.

Here’s a breakdown of the Elm code:

  1. We define a Model type that holds the content of our files.

  2. The init function sets up our initial model and sends HTTP requests to load the files.

  3. We define a Msg type for handling the results of our file loading operations.

  4. The update function handles these messages and updates our model with the loaded file contents.

  5. The view function simply displays the contents of our loaded files.

  6. The loadFile function is a helper that creates an HTTP GET request for a given filename.

  7. Finally, we set up our main program with the Elm Architecture.

To run this Elm program, you would need to:

  1. Save the Elm code in a file, e.g., EmbedExample.elm.
  2. Ensure you have the required files in a folder directory relative to where you’re serving your Elm application.
  3. Compile the Elm code to JavaScript:
$ elm make EmbedExample.elm --output=elm.js
  1. Create an HTML file that includes the compiled JavaScript and sets up a target div for Elm:
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Elm Embed Example</title>
    <script src="elm.js"></script>
  </head>
  <body>
    <div id="elm"></div>
    <script>
      var app = Elm.Main.init({
        node: document.getElementById('elm')
      });
    </script>
  </body>
</html>
  1. Serve this HTML file and the folder directory with a web server.

This Elm program demonstrates how to load and display the contents of multiple files, similar to the Go embed directive example, but using runtime file loading instead of compile-time embedding.