Как компилятор знает, как вернуть правильный тип?

У меня есть следующий код, который я не понимаю:

type Msg
    = Left | Right


content : Html Msg
content =
    p [] []

Тип подписи p:

p : List (Attribute msg) -> List (Html msg) -> Html msg

Вопрос в том, почему p может вернуть тип Msg в content функция. я знаю это Html msg а также msg может любая переменная, но она не возвращает либо Left или же Right,

2 ответа

Решение

Я попробую это сделать (не особенно обучался языкам ML или лямбда-исчислению и слишком долго работал с "{}", перенося языки, так что часть моего словарного запаса может быть отключена):

(1) Msg это тип, который специализируется на Left или же Right

(2) content это значение типа Html(Msg)

(3) content имеет значение p [] []

Давайте оценим content...

(4) p является функцией типа p : List (Attribute msg) -> List (Html msg) -> Html msg

В выражении выше msg переменная типа, мы также могли бы написать, не так запутанно:

(4а) p является функцией типа p : List (Attribute xtype) -> List (Html xtype) -> Html xtype

В синтаксисе Java это было бы что-то вроде

(4x) p является функцией типа p<XType> : List (Attribute<XType>) -> List (Html<XType>) -> Html<XType>

Таким образом, мы имеем следующее ограничение на p [] []:

  • Это типа p : List (Attribute xtype) -> List (Html xtype) -> Html xtype
  • Разрешает набирать Html Msg

это сразу говорит нам, что неизвестный тип xtype на самом деле должен быть типа Msg:

(5) p : List (Attribute Msg) -> List (Html Msg) -> Html Msg

Первый аргумент p является [], Согласно приведенной выше ограниченной подписи, тип этого выражения должен быть List (Attribute Msg), Никаких проблем с этим, механизм проверки теорем проверки типа вяза позволяет это сделать.

Второй аргумент p является [], Согласно приведенной выше ограниченной подписи, тип этого выражения должен быть List (Html Msg), С этим тоже проблем нет.

  • Таким образом, вы можете вызвать p с [] [],
  • Все, что разрешается, будет иметь тип Html Msg,

Как это возможно, если p не знает много о Msg?

Вызвать математическое мышление на основе ограничений и сделать вывод, что p [] [] должен разрешить значение типа Html x для каждого типа x, Это возможно только в том случае, если оно разрешается до значения, которое не изменяется в x - константа, полностью независимая от x, Следовательно p [] [] разрешается до некоторой тривиальной ценности. Однако ядро математического утверждения пуделя:

p : List (Attribute msg) -> List (Html msg) -> Html msg

в том, что p это то, что принимает вещи, содержащие значения типа msg и возвращает материал, содержащий значения типа msg может быть, тривиально, если p всегда возвращает константу, полностью не включающую ничего типа msg, Это будет держать любой msg как это было (потому что не было дано никакой функции преобразования msg), просто сдвиньте их как-нибудь.

Смотрите также: "Теоремы бесплатно!" Philp Wadler, 1989, для углубления в это. Вадлер начинает с этого:

Текстовый экстракт теорем бесплатно

Теперь Html type - это тип низкого уровня, который фактически не определяется языком Elm. Но для целей этого вопроса давайте представим, что Html определяется как

type Html msg
  = HtmlWithMessage HtmlNodes msg
  | HtmlWithoutMessage HtmlNodes

где HtmlNodes будет какой-то тип, представляющий фактический HTML возвращается.

Теперь, когда вы определяете Msg как type Msg = Left | Rightзатем введите Html Msg может иметь три возможных значения:

  1. HtmlWithMessage HtmlNodes Left
  2. HtmlWithMessage HtmlNodes Right
  3. HtmlWithoutMessage HtmlNodes

И так как нет сообщения в p, он бы вернулся HtmlWithoutMessage HtmlNodes,

Вопрос в том, почему p может вернуть тип Msg в content функция. я знаю это Html msg а также msg может любая переменная, но она не возвращает либо Left или же Right,

p не возвращает тип Msg, но тип Html который имеет параметр типа msg, Тип не обязан использовать параметр типа во всех его возможных значениях и может включать значения, которые вообще не используют параметр типа, например HtmlWithoutMessage HtmlNodes,

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