编译器如何知道 return 正确的类型?

How does the compiler know to return the right type?

我有以下代码,我不明白:

type Msg
    = Left | Right


content : Html Msg
content =
    p [] []

p的类型签名:

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

问题是,为什么p可以在content函数中returnMsg的类型。我知道 Html msgmsg 可以是任何变量,但它不会 return LeftRight.

我会试一试(没有特别受过 ML 语言或 Lambda 演算的训练,并且使用“{}”携带语言的时间太长,所以我的一些词汇可能不合适):

(1) Msg 是专门针对 LeftRight

的类型

(2) contentHtml(Msg)

类型的值

(3) content 的值为 p [] []

让我们评估一下 content ...

(4) pp : List (Attribute msg) -> List (Html msg) -> Html msg

类型的函数

在上面的表达式中,msg是一个类型变量,我们也可以这样写,不那么容易混淆:

(4a) pp : List (Attribute xtype) -> List (Html xtype) -> Html xtype

类型的函数

在 Java 语法中类似于

(4x) pp<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)。没问题,elm 类型检查定理证明引擎可以解决这个问题。

p 的第二个参数是 []。根据上面的约束签名,该表达式的类型必须是 List (Html Msg)。没问题。

  • 因此,您可以用 [] [] 调用 p
  • 无论它解析为什么类型,都将是 Html Msg

如果 pMsg 了解不多,那怎么可能呢?

调用基于数学约束的思维并得出结论,对于每个类型 xp [] [] 必须解析为类型 Html x 的值。这只有在它解析为一个在 x 中不变的值时才有可能——一个完全独立于 x 的常数。因此 p [] [] 解析为一些微不足道的值。然而数学断言的poodle's core

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

p 接受包含 msg 类型值的东西和 returns 包含 msg 类型值的东西,如果 [=18] 可能很简单=] 总是 returns 一个完全不涉及任何类型 msg 的常量。它会保持任何 msg 原样(因为它没有被赋予任何转换 msg 的函数),只是以某种方式移动它们。

另请参阅:"Theorems for Free!" Philp Wadler,1989 年,以深入了解这一点。 Wadler 从这个开始:

现在 Html 类型是一个非常低级的类型,它实际上并没有用 Elm 语言定义。但是为了这个问题的目的,让我们假设 Html 被定义为

type Html msg
  = HtmlWithMessage HtmlNodes msg
  | HtmlWithoutMessage HtmlNodes

其中 HtmlNodes 是表示实际 html 被 return 编辑的某种类型。

现在,当您将 Msg 定义为 type Msg = Left | Right 时,类型 Html Msg 可以具有三个可能的值:

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

并且由于 p 中没有消息,它会 return HtmlWithoutMessage HtmlNodes

The question is, why p can return the type of Msg in the content function. I know that Html msg and msg can any variable but it does not return either Left or Right.

p 不是 return 类型 Msg,而是类型参数 msgHtml 类型。该类型不需要在其所有可能值中使用类型参数,因此可以包含根本不使用类型参数的值,例如 HtmlWithoutMessage HtmlNodes.