Import Upstream version 20180207
[hcoop/debian/mlton.git] / doc / guide / localhost / EqualityTypeVariable
CommitLineData
7f918cf1
CE
1<!DOCTYPE html>\r
2<html lang="en">\r
3<head>\r
4<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">\r
5<meta name="generator" content="AsciiDoc 8.6.9">\r
6<title>EqualityTypeVariable</title>\r
7<link rel="stylesheet" href="./asciidoc.css" type="text/css">\r
8<link rel="stylesheet" href="./pygments.css" type="text/css">\r
9\r
10\r
11<script type="text/javascript" src="./asciidoc.js"></script>\r
12<script type="text/javascript">\r
13/*<![CDATA[*/\r
14asciidoc.install();\r
15/*]]>*/\r
16</script>\r
17<link rel="stylesheet" href="./mlton.css" type="text/css">\r
18</head>\r
19<body class="article">\r
20<div id="banner">\r
21<div id="banner-home">\r
22<a href="./Home">MLton 20180207</a>\r
23</div>\r
24</div>\r
25<div id="header">\r
26<h1>EqualityTypeVariable</h1>\r
27</div>\r
28<div id="content">\r
29<div id="preamble">\r
30<div class="sectionbody">\r
31<div class="paragraph"><p>An equality type variable is a type variable that starts with two or\r
32more primes, as in <span class="monospaced">''a</span> or <span class="monospaced">''b</span>. The canonical use of equality type\r
33variables is in specifying the type of the <a href="PolymorphicEquality">PolymorphicEquality</a>\r
34function, which is <span class="monospaced">''a * ''a -&gt; bool</span>. Equality type variables\r
35ensure that polymorphic equality is only used on\r
36<a href="EqualityType">equality types</a>, by requiring that at every use of a\r
37polymorphic value, equality type variables are instantiated by\r
38equality types.</p></div>\r
39<div class="paragraph"><p>For example, the following program is type correct because polymorphic\r
40equality is applied to variables of type <span class="monospaced">''a</span>.</p></div>\r
41<div class="listingblock">\r
42<div class="content"><div class="highlight"><pre><span class="k">fun</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="p">(</span><span class="n">x</span><span class="p">:</span><span class="w"> </span><span class="n">&#39;&#39;a</span><span class="p">,</span><span class="w"> </span><span class="n">y</span><span class="p">:</span><span class="w"> </span><span class="n">&#39;&#39;a</span><span class="p">):</span><span class="w"> </span><span class="n">bool</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">y</span><span class="w"></span>\r
43</pre></div></div></div>\r
44<div class="paragraph"><p>On the other hand, the following program is not type correct, because\r
45polymorphic equality is applied to variables of type <span class="monospaced">'a</span>, which is\r
46not an equality type.</p></div>\r
47<div class="listingblock">\r
48<div class="content"><div class="highlight"><pre><span class="k">fun</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="p">(</span><span class="n">x</span><span class="p">:</span><span class="w"> </span><span class="n">&#39;a</span><span class="p">,</span><span class="w"> </span><span class="n">y</span><span class="p">:</span><span class="w"> </span><span class="n">&#39;a</span><span class="p">):</span><span class="w"> </span><span class="n">bool</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">y</span><span class="w"></span>\r
49</pre></div></div></div>\r
50<div class="paragraph"><p>MLton reports the following error, indicating that polymorphic\r
51equality expects equality types, but didn&#8217;t get them.</p></div>\r
52<div class="listingblock">\r
53<div class="content monospaced">\r
54<pre>Error: z.sml 1.30-1.34.\r
55 Function applied to incorrect argument.\r
56 expects: [&lt;equality&gt;] * [&lt;equality&gt;]\r
57 but got: ['a] * ['a]\r
58 in: = (x, y)</pre>\r
59</div></div>\r
60<div class="paragraph"><p>As an example of using such a function that requires equality types,\r
61suppose that <span class="monospaced">f</span> has polymorphic type <span class="monospaced">''a -&gt; unit</span>. Then, <span class="monospaced">f 13</span> is\r
62type correct because <span class="monospaced">int</span> is an equality type. On the other hand,\r
63<span class="monospaced">f 13.0</span> and <span class="monospaced">f (fn x =&gt; x)</span> are not type correct, because <span class="monospaced">real</span> and\r
64arrow types are not equality types. We can test these facts with the\r
65following short programs. First, we verify that such an <span class="monospaced">f</span> can be\r
66applied to integers.</p></div>\r
67<div class="listingblock">\r
68<div class="content"><div class="highlight"><pre><span class="k">functor</span><span class="w"> </span><span class="n">Ok</span><span class="w"> </span><span class="p">(</span><span class="k">val</span><span class="w"> </span><span class="n">f</span><span class="p">:</span><span class="w"> </span><span class="n">&#39;&#39;a</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="n">unit</span><span class="p">):</span><span class="w"> </span><span class="k">sig</span><span class="w"> </span><span class="k">end</span><span class="w"> </span><span class="p">=</span><span class="w"></span>\r
69<span class="w"> </span><span class="k">struct</span><span class="w"></span>\r
70<span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="mi">13</span><span class="w"></span>\r
71<span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="mi">14</span><span class="w"></span>\r
72<span class="w"> </span><span class="k">end</span><span class="w"></span>\r
73</pre></div></div></div>\r
74<div class="paragraph"><p>We can do better, and verify that such an <span class="monospaced">f</span> can be applied to\r
75any integer.</p></div>\r
76<div class="listingblock">\r
77<div class="content"><div class="highlight"><pre><span class="k">functor</span><span class="w"> </span><span class="n">Ok</span><span class="w"> </span><span class="p">(</span><span class="k">val</span><span class="w"> </span><span class="n">f</span><span class="p">:</span><span class="w"> </span><span class="n">&#39;&#39;a</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="n">unit</span><span class="p">):</span><span class="w"> </span><span class="k">sig</span><span class="w"> </span><span class="k">end</span><span class="w"> </span><span class="p">=</span><span class="w"></span>\r
78<span class="w"> </span><span class="k">struct</span><span class="w"></span>\r
79<span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="p">(</span><span class="n">x</span><span class="p">:</span><span class="w"> </span><span class="n">int</span><span class="p">)</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"></span>\r
80<span class="w"> </span><span class="k">end</span><span class="w"></span>\r
81</pre></div></div></div>\r
82<div class="paragraph"><p>Even better, we don&#8217;t need to introduce a dummy function name; we can\r
83use a type constraint.</p></div>\r
84<div class="listingblock">\r
85<div class="content"><div class="highlight"><pre><span class="k">functor</span><span class="w"> </span><span class="n">Ok</span><span class="w"> </span><span class="p">(</span><span class="k">val</span><span class="w"> </span><span class="n">f</span><span class="p">:</span><span class="w"> </span><span class="n">&#39;&#39;a</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="n">unit</span><span class="p">):</span><span class="w"> </span><span class="k">sig</span><span class="w"> </span><span class="k">end</span><span class="w"> </span><span class="p">=</span><span class="w"></span>\r
86<span class="w"> </span><span class="k">struct</span><span class="w"></span>\r
87<span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="p">_</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">f</span><span class="p">:</span><span class="w"> </span><span class="n">int</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="n">unit</span><span class="w"></span>\r
88<span class="w"> </span><span class="k">end</span><span class="w"></span>\r
89</pre></div></div></div>\r
90<div class="paragraph"><p>Even better, we can use a signature constraint.</p></div>\r
91<div class="listingblock">\r
92<div class="content"><div class="highlight"><pre><span class="k">functor</span><span class="w"> </span><span class="n">Ok</span><span class="w"> </span><span class="p">(</span><span class="n">S</span><span class="p">:</span><span class="w"> </span><span class="k">sig</span><span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">f</span><span class="p">:</span><span class="w"> </span><span class="n">&#39;&#39;a</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="n">unit</span><span class="w"> </span><span class="k">end</span><span class="p">):</span><span class="w"></span>\r
93<span class="w"> </span><span class="k">sig</span><span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">f</span><span class="p">:</span><span class="w"> </span><span class="n">int</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="n">unit</span><span class="w"> </span><span class="k">end</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">S</span><span class="w"></span>\r
94</pre></div></div></div>\r
95<div class="paragraph"><p>This functor concisely verifies that a function of polymorphic type\r
96<span class="monospaced">''a -&gt; unit</span> can be safely used as a function of type <span class="monospaced">int -&gt; unit</span>.</p></div>\r
97<div class="paragraph"><p>As above, we can verify that such an <span class="monospaced">f</span> can not be used at\r
98non-equality types.</p></div>\r
99<div class="listingblock">\r
100<div class="content"><div class="highlight"><pre><span class="k">functor</span><span class="w"> </span><span class="n">Bad</span><span class="w"> </span><span class="p">(</span><span class="n">S</span><span class="p">:</span><span class="w"> </span><span class="k">sig</span><span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">f</span><span class="p">:</span><span class="w"> </span><span class="n">&#39;&#39;a</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="n">unit</span><span class="w"> </span><span class="k">end</span><span class="p">):</span><span class="w"></span>\r
101<span class="w"> </span><span class="k">sig</span><span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">f</span><span class="p">:</span><span class="w"> </span><span class="n">real</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="n">unit</span><span class="w"> </span><span class="k">end</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">S</span><span class="w"></span>\r
102\r
103<span class="k">functor</span><span class="w"> </span><span class="n">Bad</span><span class="w"> </span><span class="p">(</span><span class="n">S</span><span class="p">:</span><span class="w"> </span><span class="k">sig</span><span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">f</span><span class="p">:</span><span class="w"> </span><span class="n">&#39;&#39;a</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="n">unit</span><span class="w"> </span><span class="k">end</span><span class="p">):</span><span class="w"></span>\r
104<span class="w"> </span><span class="k">sig</span><span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">f</span><span class="p">:</span><span class="w"> </span><span class="p">(</span><span class="n">&#39;a</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="n">&#39;a</span><span class="p">)</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="n">unit</span><span class="w"> </span><span class="k">end</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">S</span><span class="w"></span>\r
105</pre></div></div></div>\r
106<div class="paragraph"><p>MLton reports the following errors.</p></div>\r
107<div class="listingblock">\r
108<div class="content monospaced">\r
109<pre>Error: z.sml 2.4-2.30.\r
110 Variable in structure disagrees with signature (type): f.\r
111 structure: val f: [&lt;equality&gt;] -&gt; _\r
112 defn at: z.sml 1.25-1.25\r
113 signature: val f: [real] -&gt; _\r
114 spec at: z.sml 2.12-2.12\r
115Error: z.sml 5.4-5.36.\r
116 Variable in structure disagrees with signature (type): f.\r
117 structure: val f: [&lt;equality&gt;] -&gt; _\r
118 defn at: z.sml 4.25-4.25\r
119 signature: val f: [_ -&gt; _] -&gt; _\r
120 spec at: z.sml 5.12-5.12</pre>\r
121</div></div>\r
122</div>\r
123</div>\r
124<div class="sect1">\r
125<h2 id="_equality_type_variables_in_type_and_datatype_declarations">Equality type variables in type and datatype declarations</h2>\r
126<div class="sectionbody">\r
127<div class="paragraph"><p>Equality type variables can be used in type and datatype declarations;\r
128however they play no special role. For example,</p></div>\r
129<div class="listingblock">\r
130<div class="content"><div class="highlight"><pre><span class="k">type</span><span class="w"> </span><span class="n">&#39;a</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">&#39;a</span><span class="w"> </span><span class="n">*</span><span class="w"> </span><span class="n">int</span><span class="w"></span>\r
131</pre></div></div></div>\r
132<div class="paragraph"><p>is completely identical to</p></div>\r
133<div class="listingblock">\r
134<div class="content"><div class="highlight"><pre><span class="k">type</span><span class="w"> </span><span class="n">&#39;&#39;a</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">&#39;&#39;a</span><span class="w"> </span><span class="n">*</span><span class="w"> </span><span class="n">int</span><span class="w"></span>\r
135</pre></div></div></div>\r
136<div class="paragraph"><p>In particular, such a definition does <em>not</em> require that <span class="monospaced">t</span> only be\r
137applied to equality types.</p></div>\r
138<div class="paragraph"><p>Similarly,</p></div>\r
139<div class="listingblock">\r
140<div class="content"><div class="highlight"><pre><span class="k">datatype</span><span class="w"> </span><span class="n">&#39;a</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="k">of</span><span class="w"> </span><span class="n">&#39;a</span><span class="w"></span>\r
141</pre></div></div></div>\r
142<div class="paragraph"><p>is completely identical to</p></div>\r
143<div class="listingblock">\r
144<div class="content"><div class="highlight"><pre><span class="k">datatype</span><span class="w"> </span><span class="n">&#39;&#39;a</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="k">of</span><span class="w"> </span><span class="n">&#39;&#39;a</span><span class="w"></span>\r
145</pre></div></div></div>\r
146</div>\r
147</div>\r
148</div>\r
149<div id="footnotes"><hr></div>\r
150<div id="footer">\r
151<div id="footer-text">\r
152</div>\r
153<div id="footer-badges">\r
154</div>\r
155</div>\r
156</body>\r
157</html>\r