Question regarding guide.elm-lang (Forms)

I’m going over the guide, and I wonder why it uses Html Msg for the view function, but Html msg for the view helper functions, (and get (String -> msg) argument). instead of also using Html Msg… I’ve tested, and it works both ways - is there any reason for using msg instead of Msg? Why does it even work?

And can you help me make sense of the syntax (String -> msg), I would have thought it should be (Msg -> String), or (Msg String), since when I return a Msg type, I write it as SomeMsg "arg", so it seems like Msg takes the additional arg as an argument, making it (Msg -> String).

Assuming Msg is define as

type Msg = SomeMsg: String

Is it because SomeMsg is actually a function taking a string and returning a Msg? And then (String -> msg) also works, since msg can stand for anything, and it gets automatically converted to Msg because view returns Msg?

Here’s a snippet of the relevant code:

view : Model -> Html Msg
view model =
  div []
    [ viewInput "text" "Name" model.name Name
    , viewInput "password" "Password" model.password Password
    , viewInput "password" "Re-enter Password" model.passwordAgain PasswordAgain
    , viewValidation model
    ]


viewInput : String -> String -> String -> (String -> msg) -> Html msg
viewInput t p v toMsg =
  input [ type_ t, placeholder p, value v, onInput toMsg ] []


viewValidation : Model -> Html msg
viewValidation model =
  if model.password == model.passwordAgain then
    div [ style "color" "green" ] [ text "OK" ]
  else
    div [ style "color" "red" ] [ text "Passwords do not match!" ]

Lowercase msg means it can work with any message type

I will try to answer your questions. I will probably get things wrong or explain them badly, but there surely will be other people also giving some input.

is there any reason for using msg instead of Msg ? Why does it even work?

If you use the uppercase Msg you directly refer to that type. If you were to misstype and write Mssg it would fail, because that type doesn’t exist.
If you use a lowercase msg like in Html msg that’s basically just giving a name to a “unspecific” type and you could also write Html a or Html whatever. The type Html simply needs a second type (making it Html x, so to say) and in the cases where you don’t care what the second type is you can lowercase the second part to indicate that.

And can you help me make sense of the syntax (String -> msg)

That part is saying that you expect a function as an argument. In your specific example it’s saying:

“Give me a function that i can pass in a String and that then returns me an unspecified type msg!”

If that part were saying (Int -> String) then it would be saying:

“Give me a function that i can pass in an Int, so a number, and i will return you a String)!”

In your example the view function viewInput is simply saying:
“I need a function from you. I will use that function to create a Msg for your update. That function, that you give me, needs to expect a String.”

That the function that you pass in should expect a string, should make sense to you: Somehow you will want to “know”, what currently is written in the input you show to the user, right?

1 Like

Also consider that functions that use msg are generic and can be used anywhere. Function that use Msg are tied to your messages type so cannot be recycled.

Moreover, every function can be converted to use msg or Msg. To convert from Msg to msg you need to pass extra parameters containing the type constructors that can do this conversion. (String -> msg) in your example above.

Thanks for the explanation! What I was missing is the fact that type variants are actually functions returning that type. The guide explains it well, I just had to have patience and continue on reading :slight_smile:

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.