Что такое аннотация `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). Определение () здесь означает, что вы не ожидаете никаких флагов.

Как работают флаги, более подробно объясняется в руководстве

Другие вопросы по тегам