I have the following code, that I do not understand:
type Msg
= Left | Right
content : Html Msg
content =
p [] []
The type signature of p:
p : List (Attribute msg) -> List (Html msg) -> Html msg
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.
I will take a shot at this (not particularly trained in ML languages or Lambda calculus, and worked with '{}' carrying languages for far too long, so some of my vocabulary may be off):
(1)
Msgis a type that specializes to eitherLeftorRight(2)
contentis a value of typeHtml(Msg)(3)
contenthas valuep [] []Let's evaluate
content...(4)
pis a function of typep : List (Attribute msg) -> List (Html msg) -> Html msgIn the expression above
msgis a type variable, we could also write, less confusingly:(4a)
pis a function of typep : List (Attribute xtype) -> List (Html xtype) -> Html xtypeIn Java syntax that would be something like
(4x)
pis a function of typep<XType> : List (Attribute<XType>) -> List (Html<XType>) -> Html<XType>So we have the following constraint on
p [] []:p : List (Attribute xtype) -> List (Html xtype) -> Html xtypeHtml Msgthis immediately tells us that unknown type
xtypemust actually be typeMsg:(5)
p : List (Attribute Msg) -> List (Html Msg) -> Html MsgThe first argument to
pis[]. According to the constrained signature above, the type of that expression must beList (Attribute Msg). No problem with that, the elm type checking theorem proving engine lets this through.The second argument to
pis[]. According to the constrained signature above, the type of that expression must beList (Html Msg). No problem with that either.pwith[] [].Html Msg.How is that possible if
pdoesn't know much aboutMsg?Invoke mathematical constraint-based thinking and conclude that
p [] []must resolve to a value of typeHtml xfor every typex. This is only possible if it resolves to a value that does not vary inx- a constant completely independent ofx. Thereforep [] []resolves to some trivial value. However the poodle's core of the mathematical assertion:p : List (Attribute msg) -> List (Html msg) -> Html msgis that
pis something that takes stuff containing values of typemsgand returns stuff containing values of typemsg, maybe trivially so ifpalways returns a constant completely not involving anything of typemsg. It will keep anymsgas it was (because it has not been given any function transformingmsg), just shift them around somehow.See also: "Theorems for Free!" by Philp Wadler, 1989 for going deeper into this. Wadler starts off with this: