What does it mean by `Html Msg`?
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:
-
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
-
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
}
- Remember, the type parameters must line up. So
msg
must refer to the same type everywhere regardless of whether it isInt
or aMsg
custom type - 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 typemsg
is the type for “what event type does this DOM node trigger”