Что означает функция с 2 значениями в правой части? (Модель → Html msg)
Я столкнулся с этим в руководстве:
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 ]
Итак, это функция, которая принимает значение Model
.
Html msg
обычно выглядит так, как будто мы вызываем функцию Html
с аргументом msg
.
msg
, похоже, не играет никакой роли ни в какой другой части функции viewValidation
. Итак, что это значит и что это значит в этом случае?
Ответы
Ответ 1
Html Msg
- это просто параметр типа, поскольку List Int
is. Пока List Int
обозначает список, содержащий элемент типа Int
, аналогично Html Msg
описывает некоторый HTML, который может обрабатывать/выдавать сообщения типа Msg
.
Например, если у вас есть кнопка внутри HTML, она может выглядеть так:
button [ onClick DoSomething ] [ text "caption" ]
Где DoSomething
- это случай типа Msg
.
Ответ 2
Не смешивайте определение типа с нормальным выполнением кода. Html
не является функцией, это тип, который принимает параметр для определения типа для функции вида.
Html msg
- это самое общее определение, которое вы можете иметь в качестве msg
- это сама переменная, поэтому это возвращает Html, который не зависит от используемого вами типа msg. Это может быть либо из-за того, что он не создает сообщений о событиях, либо потому, что функция просмотра принимает сообщения как параметры.
Поскольку установленные комментарии Html ()
были бы очень узким типом, который был бы вынужден ничего не возвращать.
Наиболее распространенным случаем является функция представления, возвращающая Html msg
- i.e.Html с сообщениями на основе пользовательских взаимодействий.
Поскольку Elm поощряет компонентность, вам также нужно иметь в виду Html.map
. Это подпись типа Html.map : (a -> b) -> Html a -> Html b
. В контексте компонентов это легче читать как
Html.map : (Child.Msg -> Parent.Msg) -> Html Child.Msg -> Html Parent.Msg
Обратите внимание, что когда вы определяете свои сообщения в своем родительском компоненте, у вас будет что-то вроде:
type Msg = ChildMsg Child.Msg
что означает, что ChildMsg
имеет подпись типа:
ChildMsg : Child.Msg -> Parent.Msg
Таким образом, мои функции просмотра имеют много
parentView model =
-- childView model.child |> Html.map ChildMsg
Html.map ChildMsg (childView model.child)