Что такое аннотация `init: () -> (Model, Cmd Msg)? - PullRequest
3 голосов
/ 10 марта 2019

На официальном веб-сайте 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 Ответ

7 голосов
/ 10 марта 2019

Да, init - это функция. () называется типом "единица измерения". Это тип, который имеет только одно значение, (), которое также называется "единицей".

Теперь я уверен, что вы спрашиваете: «Ну, это кажется довольно бесполезным. Какой смысл иметь аргумент функции, который может быть только одной вещью?». Ответ в том, что это очень полезно, если вы пишете что-то общее, что может взять что-то , но не всегда.

В этом случае Browser.element указывает, что init должен иметь тип flags -> ( model, Cmd msg ), где flags - это переменная типа, которая может быть любой. Поскольку Browser.element никак не ограничивает flags, вы можете заменить его на что угодно, и он все равно должен скомпилироваться.

Обратите внимание, что Browser.element немного волшебно. Во время выполнения Elm рассмотрит тип, назначенный вами для flags, и ожидает, что вы передадите ему значение этого типа из JavaScript. Если вы этого не сделаете, то это один из очень немногих случаев, когда Elm завершится с ошибкой во время выполнения (хотя, технически, он потерпит неудачу, прежде чем какой-либо код Elm будет запущен, потому что вы допустили ошибку на стороне JavaScript). Указание () означает, что вы не ожидаете никаких флагов.

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

...