Как компилятор знает, как вернуть правильный тип?
У меня есть следующий код, который я не понимаю:
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
может иметь три возможных значения:
HtmlWithMessage HtmlNodes Left
HtmlWithMessage HtmlNodes Right
HtmlWithoutMessage HtmlNodes
И так как нет сообщения в p
, он бы вернулся HtmlWithoutMessage HtmlNodes
,
Вопрос в том, почему
p
может вернуть типMsg
вcontent
функция. я знаю этоHtml msg
а такжеmsg
может любая переменная, но она не возвращает либоLeft
или жеRight
,
p
не возвращает тип Msg
, но тип Html
который имеет параметр типа msg
, Тип не обязан использовать параметр типа во всех его возможных значениях и может включать значения, которые вообще не используют параметр типа, например HtmlWithoutMessage HtmlNodes
,