我有以下我不理解的代码:
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
。
答案 0 :(得分:4)
我将对此进行拍摄(不是特别受过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)
。没问题,榆木类型检查定理证明引擎可以解决这个问题。
p
的第二个参数是[]
。根据上面的约束签名,该表达式的类型必须为List (Html Msg)
。没问题。
p
来调用[] []
。 Html Msg
类型的任何内容。如果p
对Msg
不太了解怎么办?
调用基于数学约束的思维,并得出结论,对于每种类型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年,对它进行了更深入的研究。瓦德勒从此开始:
答案 1 :(得分:0)
现在Html
类型太低了,以至于实际上并没有用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
。类型不需要在所有可能的值中都使用type参数,因此可以包含根本不使用type参数的值,例如HtmlWithoutMessage HtmlNodes
。