Skip to content

Commit f308d70

Browse files
committed
Change \rm to \mathrm in hm article
1 parent 4b22738 commit f308d70

File tree

1 file changed

+37
-35
lines changed

1 file changed

+37
-35
lines changed

posts/2024-01-11-hm-generalisation.md

Lines changed: 37 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -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

4141
where $\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
4343
definition 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

5353
Instantiation 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
6767
the type of a variable is now as simple as looking up the type scheme in the
6868
environment, 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

7979
Let-polymorphism is a very useful concept in the Hindley-Milner calculus,
8080
since it's the only way to define polymorphic functions and values. That means a
8181
term 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
8383
type 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

9090
Now let's look at a more complex example: let's add some rules for lists.
@@ -98,32 +98,33 @@ $$
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

114114
Now 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
127128
polymorphic list. As mentioned before, in the Hindley-Milner calculus,
128129
variables cannot be assigned to after they are defined. But in the case of
129130
imperative 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]$.
155157
This isn't really the expected type for `map`, so what goes wrong here? Well, the
156158
generalisation of `result` causes the value in the return statement to be instantiated
157159
with a type independent of other uses of `result`. Since we reassign
@@ -164,12 +166,12 @@ $$
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

Comments
 (0)