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

时间:2018-09-29 06:25:57

标签: type-inference elm type-theory

我有以下我不理解的代码:

type Msg
    = Left | Right


content : Html Msg
content =
    p [] []

p的类型签名:

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

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

2 个答案:

答案 0 :(得分:4)

我将对此进行拍摄(不是特别受过ML语言或Lambda演算训练的人,并且使用'{}'语言进行了太长时间了,所以我的某些词汇可能会用完了)

(1)Msg是专门用于LeftRight

的类型

(2)content是类型Html(Msg)

的值

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

让我们评估content ...

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

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

  • 因此,您可以使用p来调用[] []
  • 它将解析为Html Msg类型的任何内容。

如果pMsg不太了解怎么办?

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

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

p接收包含类型msg的值的东西,并返回包含类型msg的值的东西,也许很简单,所以如果p总是返回常量完全不涉及任何msg类型的东西。它将保持任何msg的状态(因为尚未提供任何转换msg的功能),只需以某种方式移动它们即可。

另请参阅:"Theorems for Free!",作者是Philp Wadler,1989年,对它进行了更深入的研究。瓦德勒从此开始:

Text Extract of Theorems for Free!

答案 1 :(得分:0)

现在Html类型太低了,以至于实际上并没有用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 msgmsg可以有任何变量,但不会返回LeftRight

p不是返回类型Msg,而是返回类型参数为Html的类型msg。类型不需要在所有可能的值中都使用type参数,因此可以包含根本不使用type参数的值,例如HtmlWithoutMessage HtmlNodes

相关问题