@@ -33,21 +33,21 @@ formally, we define generalisation using the following function:
3333
3434$$
3535\begin{gather*}
36- \rm {Gen}:\Gamma\times \tau\to\sigma\\
37- \rm {Gen}=(\Gamma,\tau)\mapsto \forall(\rm{ftv}(\tau)\setminus\rm{ftv}(\Gamma)).\tau
36+ \mathrm {Gen}:\Gamma\times \tau\to\sigma\\
37+ \mathrm {Gen}=(\Gamma,\tau)\mapsto \forall(\rm{ftv}(\tau)\setminus\rm{ftv}(\Gamma)).\tau
3838\end{gather*}
3939$$
4040
4141where $\tau$ is the set of types, and $\sigma$ the set of type schemes, and
42- $\rm {ftv}(x)$ denotes the set of free type variables in $x$. With that
42+ $\mathrm {ftv}(x)$ denotes the set of free type variables in $x$. With that
4343definition in mind, we can define type inference for let-in expressions as follows:
4444
4545$$
4646\dfrac
4747 {\Gamma\vdash e_0:\tau_0,S_0\quad
48- S_0\Gamma\cup\{x:\rm {Gen}(\Gamma,\tau_0)\}\vdash e_1:\tau_1,S_1}
48+ S_0\Gamma\cup\{x:\mathrm {Gen}(\Gamma,\tau_0)\}\vdash e_1:\tau_1,S_1}
4949 {\Gamma\vdash\textbf{let } x=e_0\textbf{ in }e_1:\tau_1,S_0S_1}
50- [\rm {Let}]
50+ [\mathrm {Let}]
5151$$
5252
5353Instantiation isn't difficult either: we take a type scheme, and consistently replace
@@ -57,34 +57,34 @@ as follows:
5757
5858$$
5959\begin{gather*}
60- \rm {inst}:\sigma\to\tau\\
61- \rm {inst}=(\forall\alpha_1,\ldots,\alpha_n.\tau)\mapsto \tau[\alpha_1:=\rm{fresh},
62- \ldots,\alpha_n:=\rm {fresh}]
60+ \mathrm {inst}:\sigma\to\tau\\
61+ \mathrm {inst}=(\forall\alpha_1,\ldots,\alpha_n.\tau)\mapsto \tau[\alpha_1:=\rm{fresh},
62+ \ldots,\alpha_n:=\mathrm {fresh}]
6363\end{gather*}
6464$$
6565
66- where $\rm {fresh}$ denotes a fresh type variable that is free in $\tau$. Inferring
66+ where $\mathrm {fresh}$ denotes a fresh type variable that is free in $\tau$. Inferring
6767the type of a variable is now as simple as looking up the type scheme in the
6868environment, and instantiating the found type scheme.
6969
7070$$
7171\dfrac
7272 {x:\sigma\in\Gamma}
73- {\Gamma\vdash x:\rm {inst}(\sigma),\emptyset}
74- [\rm {Var}]
73+ {\Gamma\vdash x:\mathrm {inst}(\sigma),\emptyset}
74+ [\mathrm {Var}]
7575$$
7676
7777## To generalise?
7878
7979Let-polymorphism is a very useful concept in the Hindley-Milner calculus,
8080since it's the only way to define polymorphic functions and values. That means a
8181term like the following will be accepted by Hindley-Milner, because $f$ has the
82- inferred type $\alpha\to\alpha$, and running that through $\rm {Gen}$ gives the
82+ inferred type $\alpha\to\alpha$, and running that through $\mathrm {Gen}$ gives the
8383type scheme $\forall\alpha.\alpha\to\alpha$.
8484
8585$$
86- \textbf{let }f=\lambda x.x\textbf{ in }(f\ 10, f\ \rm {True})
87- :\rm {Int}\times\rm{Bool}
86+ \textbf{let }f=\lambda x.x\textbf{ in }(f\ 10, f\ \mathrm {True})
87+ :\mathrm {Int}\times\rm{Bool}
8888$$
8989
9090Now let's look at a more complex example: let's add some rules for lists.
9898\dfrac
9999 {\begin{matrix}
100100 \Gamma\vdash e_0:\tau_0,S_0\quad\ldots\quad\Gamma\vdash e_n:\tau_n,S_n\\
101- \tau=\rm {fresh}\quad
101+ \tau=\mathrm {fresh}\quad
102102 \tau\stackrel{U_0}\sim\tau_0\quad\ldots\quad\tau\stackrel{U_n}\sim\tau_n
103103 \end{matrix}}
104- {\Gamma\vdash[e_0,\ldots,e_n]:\rm {List}[\tau],S_0\ldots S_nU_0\ldots U_n}
105- [\rm {List}\text{-}\rm{lit}]\\
104+ {\Gamma\vdash[e_0,\ldots,e_n]:\mathrm {List}[\tau],S_0\ldots S_nU_0\ldots U_n}
105+ [\mathrm {List}\text{-}\rm{lit}]\\
106106\\
107107\dfrac
108- {\Gamma\vdash e_0:\tau,S_0\quad S_0\Gamma\vdash e_1:\rm {List}[\tau],S_1}
109- {\Gamma\vdash e_0::e_1:\rm {List}[\tau],S_0S_1}
110- [\rm {List}\text{-}\rm{cons}]
108+ {\Gamma\vdash e_0:\tau,S_0\quad S_0\Gamma\vdash e_1:\mathrm {List}[\tau],S_1}
109+ {\Gamma\vdash e_0::e_1:\mathrm {List}[\tau],S_0S_1}
110+ [\mathrm {List}\text{-}\rm{cons}]
111111\end{gather*}
112112$$
113113
114114Now using these new concepts, we can infer and check the type of the following
115- program. Note that we abuse the let-polymorphism here, since $[ ] :\rm{List}[ \alpha] $
116- and, therefore according to the $[ \rm{Let}] $ rule, $x:\forall\alpha.\rm{List}[ \alpha] $
117- is added to the environment. And with the $[ \rm{Var}] $ rule, we can instantiate $x$
118- as both a $\rm{List}[ \rm{Int}] $ and a $\rm{List}[ \rm{Bool}] $ in the same body.
115+ program. Note that we abuse the let-polymorphism here, since $[ ] :\mathrm{List}[ \alpha] $
116+ and, therefore according to the $[ \mathrm{Let}] $ rule, $x:\forall\alpha.\rm{List}[ \alpha] $
117+ is added to the environment. And with the $[ \mathrm{Var}] $ rule, we can
118+ instantiate $x$ as both a $\mathrm{List}[ \rm{Int}] $ and a $\rm{List}[ \rm{Bool}] $
119+ in the same body.
119120
120121$$
121- \textbf{let }x=[]\textbf{ in }(10::x,\rm {True} :: x)
122- :\rm {List}[\rm{Int}]\times\rm{List}[\rm{Bool}]
122+ \textbf{let }x=[]\textbf{ in }(10::x,\mathrm {True} :: x)
123+ :\mathrm {List}[\rm{Int}]\times\rm{List}[\rm{Bool}]
123124$$
124125
125- As we've seen with functions, the generalisation in the $[ \rm {Let}] $ rule and
126- the instantiation in the $[ \rm {Var}] $ rule are hard at work to handle the
126+ As we've seen with functions, the generalisation in the $[ \mathrm {Let}] $ rule and
127+ the instantiation in the $[ \mathrm {Var}] $ rule are hard at work to handle the
127128polymorphic list. As mentioned before, in the Hindley-Milner calculus,
128129variables cannot be assigned to after they are defined. But in the case of
129130imperative or object-oriented languages, reassignment should be allowed,
@@ -147,11 +148,12 @@ End
147148```
148149
149150` result ` is a definition we have seen before, so we can quickly conclude that
150- $\text{result}:\forall\alpha.\rm{List}[ \alpha] $. Now the use of ` result ` in the for
151- loop causes it to get instantiated and become a value of type $\rm{List}[ \beta] $,
152- and similarly, the use in the return statement also gets instantiated to a value
153- of type $\rm{List}[ \gamma] $. So the type of ` map ` is inferred as
154- $\forall\alpha,\beta,\gamma.(\alpha\to\beta)\times\rm{List}[ \alpha] \to\rm{List}[ \gamma] $.
151+ $\text{result}:\forall\alpha.\mathrm{List}[ \alpha] $. Now the use of ` result ` in the
152+ for loop causes it to get instantiated and become a value of type
153+ $\mathrm{List}[ \beta] $, and similarly, the use in the return statement also
154+ gets instantiated to a value of type $\mathrm{List}[ \gamma] $. So the type of ` map `
155+ is inferred as $\forall\alpha,\beta,\gamma.(\alpha\to\beta)
156+ \times\mathrm{List}[ \alpha] \to\rm{List}[ \gamma] $.
155157This isn't really the expected type for ` map ` , so what goes wrong here? Well, the
156158generalisation of ` result ` causes the value in the return statement to be instantiated
157159with a type independent of other uses of ` result ` . Since we reassign
164166\dfrac
165167 {\Gamma\vdash e_0:\tau_0,S_0\quad S_0\Gamma\cup\{x:\tau_0\}\vdash e_1:\tau_1,S_1}
166168 {\Gamma\vdash\textbf{let }x=e_0\textbf{ in }e_1:\tau_1,S_0S_1}
167- [\rm {Let}\text{-}\lnot\rm{Gen}]\\
169+ [\mathrm {Let}\text{-}\lnot\rm{Gen}]\\
168170\\
169171\dfrac
170172 {x:\tau\in\Gamma}
171173 {\Gamma\vdash x:\tau,\emptyset}
172- [\rm {Var}\text{-}\lnot\rm{inst}]
174+ [\mathrm {Var}\text{-}\lnot\rm{inst}]
173175\end{gather*}
174176$$
175177
0 commit comments