There are possibly 2 questions in this question. I’ll answer them 1 by 1

Part 1: h-t-m-l message

After knowing the basic Elm syntax, we could be reading the following “return values” like this

userFromJWT : String -> Maybe User
-- returns a User value or nothing
split : String -> List String
-- returns a list of String

With the help from our prior programming experience, we treat the return values as *User and []String and jumps directly to think in terms of “How do I use a var u *User value? u.name?” and “How do I use a var s String? String.length(s)?”

We don’t actually “see” the words Maybe or List; our attention was focused on User and String.

If we proceed with these instincts alone, we’ll fumble when we see unfamiliar types. We’d ask the wrong questions

view : Model -> Html Msg
-- returns an h-t-m-l message... but how do I return such a message?
userEmail : Json.Decode.Decoder String
-- returns a json decode decoder string... but how do I return such a string?

There are no answers to the questions because there’s a misunderstanding of the grammar. To avoid being misled by my prior programming experience, I do this one weird trick instead:

  1. Just focus on the first word

     Html Msg
     ^^^^
     -- and read "Html" type
    
    
     Json.Decode.Decoder String
     ^^^^^^^^^^^^^^^^^^^
     -- and read "Json.Decode.Decoder" type
    
    
     HelloWorld (Html msg) (Json.Decode.Decoder String)
     ^^^^^^^^^^
     -- and read "HelloWorld" type
    
  2. Then look at the documentation for that word; look for functions that returns that word

Here are some functions that I found with text search -> Html on in the Html docs page

text : String -> Html msg
div : List (Attribute msg) -> List (Html msg) -> Html msg
span : List (Attribute msg) -> List (Html msg) -> Html msg

-- note: unfamiliar types like `Attribute` usually refers to a type defined in the same module, i.e. `Html.Attribute`. You may have to search around for it

And calling any of the these functions will be able to give us a value of Html type, just provide the necessary input argument values.

Here are some functions that I found returning Decoder in the docs page of Json.Decode (there wasn’t a page on Json.Decode.Decoder alone)

string : Decoder String
int : Decoder Int
list : Decoder a -> Decoder (List a)
field : String -> Decoder a -> Decoder a
oneOf : List (Decoder a) -> Decoder a

Same idea: calling any of the these functions will be able to give us a value of Json.Decode.Decoder type, just provide the necessary input argument values.

Part 2 Ok, but what is this Html type

In an Elm Browser program we are required to provide a view function that returns Html type. We can deduce Elm takes this return value and renders the corresponding DOM nodes in the browser.

view : model -> Html msg
view model =
    Html.h1 [ Html.Attributes.class "greeting" ] [ Html.text "Hello" ]

will render

<h1 class="greeting">Hello</h1>

The Html module does not export the internal details of this type for us to look at (aka it’s an opaque type). The module only exports a bunch of functions for us to call, to obtain various Html values. And really that’s all we can know about it.

Part 2b And what’s the relevance of msg part?

That’s the type parameter of Html type. We can’t always have an effective mental model of what role they play. Sometimes we can deduce easily, e.g. Maybe Int or List String. But other times, it’s not as obvious

string : Parser (String -> a) a

What we can practically do with them is to make sure the type parameters / associated data types align, e.g.

map : (a -> b) -> a -> b
map func arg =
    ...

To “line up” the type parameters.. i’ll make sure the the a types are the same. And similarly:

h1 : List (Attribute msg) -> List (Html msg) -> Html msg

When we call Html.h1 we can give any list of attributes and list of inner html elements – as long as their msg are the same type.

Now, if we go back up and look at a Browser program signature, e.g. Browser.sandbox

sandbox :
    { init : model
    , view : model -> Html msg
    , update : msg -> model -> model
    }
  1. Remember, the type parameters must line up. So msg must refer to the same type everywhere regardless of whether it is Int or a Msg custom type
  2. Recall that

    update — a way to update your state based on messages https://guide.elm-lang.org/architecture/

This means the msg in Html msg refers to the type of value that will be handled in your update function. So we can conclude that

  • Html is the DOM node type
  • msg is the type for “what event type does this DOM node trigger”