Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does a function with 2 values on the right side mean? (Model -> Html msg)

Tags:

elm

I have encountered that in the guide:

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

So this is a function, which takes the Model. Html msg usually looks to me like we are calling the function Html with the argument msg.

msg doesn't seem to play any role in any other part of the viewValidation function, though. So what does it mean and what is it for in this case?

like image 630
MoeSattler Avatar asked May 21 '16 13:05

MoeSattler


2 Answers

Html Msg is just a type parameter, as List Int is. While List Int denotes a list that contains element of type Int, similarly Html Msg describes some HTML that can treat/emit messages of type Msg.

For example, if you have a button inside your HTML, it could look like this:

button [ onClick DoSomething ] [ text "caption" ]

Where DoSomething is a case of the Msg type.

like image 129
marcosh Avatar answered Nov 07 '22 20:11

marcosh


Don't mix the type definition with the normal execution of code. Html is not a function, it is a type that takes a parameter to define a type for a view function.

Html msg is the most general definition you can have as msg is a variable itself, so this returns Html that is independent of the msg type you are currently using. This could either be because it creates no event messages, or because the view function takes messages as parameters.

As the comments established Html () would be a very narrow type that is constrained to return nothing.

The most common case though will be a view function returning Html Msg - i.e. Html with messages based on user interactions.

As Elm encourages componentization, you also need keep Html.map in mind. It's type signature is Html.map : (a -> b) -> Html a -> Html b. In the context of components this is more easily read as

Html.map : (Child.Msg -> Parent.Msg) -> Html Child.Msg -> Html Parent.Msg

Note that when you define your messages in your parent component, you will have something like:

type Msg = ChildMsg Child.Msg

which means that ChildMsg has type signature:

ChildMsg : Child.Msg -> Parent.Msg

So my view functions have a lot of

parentView model = 
  -- childView model.child |> Html.map ChildMsg
  Html.map ChildMsg (childView model.child)
like image 8
Simon H Avatar answered Nov 07 '22 20:11

Simon H