编译器如何知道 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 msg
和 msg
可以是任何变量,但它不会 return Left
或 Right
.
我会试一试(没有特别受过 ML 语言或 Lambda 演算的训练,并且使用“{}”携带语言的时间太长,所以我的一些词汇可能不合适):
(1) Msg
是专门针对 Left
或 Right
的类型
(2) content
是 Html(Msg)
类型的值
(3) content
的值为 p [] []
让我们评估一下 content
...
(4) p
是 p : List (Attribute msg) -> List (Html msg) -> Html msg
类型的函数
在上面的表达式中,msg
是一个类型变量,我们也可以这样写,不那么容易混淆:
(4a) 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)
。没问题,elm 类型检查定理证明引擎可以解决这个问题。
p
的第二个参数是 []
。根据上面的约束签名,该表达式的类型必须是 List (Html Msg)
。没问题。
- 因此,您可以用
[] []
调用 p
。
- 无论它解析为什么类型,都将是
Html Msg
。
如果 p
对 Msg
了解不多,那怎么可能呢?
调用基于数学约束的思维并得出结论,对于每个类型 x
,p [] []
必须解析为类型 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
可以具有三个可能的值:
HtmlWithMessage HtmlNodes Left
HtmlWithMessage HtmlNodes Right
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
,而是类型参数 msg
的 Html
类型。该类型不需要在其所有可能值中使用类型参数,因此可以包含根本不使用类型参数的值,例如 HtmlWithoutMessage HtmlNodes
.
我有以下代码,我不明白:
type Msg
= Left | Right
content : Html Msg
content =
p [] []
p
的类型签名:
p : List (Attribute msg) -> List (Html msg) -> Html msg
问题是,为什么p
可以在content
函数中returnMsg
的类型。我知道 Html msg
和 msg
可以是任何变量,但它不会 return Left
或 Right
.
我会试一试(没有特别受过 ML 语言或 Lambda 演算的训练,并且使用“{}”携带语言的时间太长,所以我的一些词汇可能不合适):
(1) Msg
是专门针对 Left
或 Right
(2) content
是 Html(Msg)
(3) content
的值为 p [] []
让我们评估一下 content
...
(4) p
是 p : List (Attribute msg) -> List (Html msg) -> Html msg
在上面的表达式中,msg
是一个类型变量,我们也可以这样写,不那么容易混淆:
(4a) 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)
。没问题,elm 类型检查定理证明引擎可以解决这个问题。
p
的第二个参数是 []
。根据上面的约束签名,该表达式的类型必须是 List (Html Msg)
。没问题。
- 因此,您可以用
[] []
调用p
。 - 无论它解析为什么类型,都将是
Html Msg
。
如果 p
对 Msg
了解不多,那怎么可能呢?
调用基于数学约束的思维并得出结论,对于每个类型 x
,p [] []
必须解析为类型 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
可以具有三个可能的值:
HtmlWithMessage HtmlNodes Left
HtmlWithMessage HtmlNodes Right
HtmlWithoutMessage HtmlNodes
并且由于 p
中没有消息,它会 return HtmlWithoutMessage HtmlNodes
。
The question is, why
p
can return the type ofMsg
in thecontent
function. I know thatHtml msg
andmsg
can any variable but it does not return eitherLeft
orRight
.
p
不是 return 类型 Msg
,而是类型参数 msg
的 Html
类型。该类型不需要在其所有可能值中使用类型参数,因此可以包含根本不使用类型参数的值,例如 HtmlWithoutMessage HtmlNodes
.