Что такое аннотация `init: () -> (Model, Cmd Msg)?
На официальном сайте Elm есть init
определение функции я не понимаю:
init : () -> (Model, Cmd Msg)
init _ =
( Loading
, Http.get
{ url = "https://elm-lang.org/assets/public-opinion.txt"
, expect = Http.expectString GotText
}
)
Так init
функция возвращает tuple
, то почему бы не определить его обозначения как:
init: (Model, Cmd Msg)
Но в их образце init
возвращает функцию, которая возвращает tuple
, Это правда?
И как читать ()
в init : () -> (Model, Cmd Msg)
? Например, я могу сказать, что-нибудь вернуть кортеж?
1 ответ
Да, init
это функция. ()
называется "единичным" типом. Это тип, который имеет только одно значение, ()
, который также называется "блок".
Теперь я уверен, что вы спрашиваете: "Ну, это кажется довольно бесполезным. Какой смысл иметь аргумент функции, который может быть только одним?". Ответ в том, что это очень полезно, если вы пишете что-то общее, что может потребовать чего-то, но не всегда.
В этом случае, Browser.element
указывает, что init
должен иметь тип flags -> ( model, Cmd msg )
, где flags
переменная типа, которая может быть чем угодно. поскольку Browser.element
не стесняет flags
любым другим способом, вы можете заменить его на то, что вы хотите, и он все равно должен скомпилироваться.
Обратите внимание, что Browser.element
немного волшебства Во время выполнения Elm рассмотрит тип, который вы назначили flags
и ожидаем, что вы передадите ему значение этого типа из JavaScript. Если вы этого не сделаете, то это один из очень немногих случаев, когда Elm завершится с ошибкой во время выполнения (хотя, технически, он потерпит неудачу, прежде чем какой-либо код Elm будет запущен, потому что вы допустили ошибку на стороне JavaScript). Определение ()
здесь означает, что вы не ожидаете никаких флагов.
Как работают флаги, более подробно объясняется в руководстве