Import Upstream version 20180207
[hcoop/debian/mlton.git] / doc / guide / localhost / TypeChecking
... / ...
CommitLineData
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>TypeChecking</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>TypeChecking</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>MLton&#8217;s type checker follows the <a href="DefinitionOfStandardML">Definition</a>\r
32closely, so you may find differences between MLton and other SML\r
33compilers that do not follow the Definition so closely. In\r
34particular, SML/NJ has many deviations from the Definition&#8201;&#8212;&#8201;please\r
35see <a href="SMLNJDeviations">SMLNJDeviations</a> for those that we are aware of.</p></div>\r
36<div class="paragraph"><p>In some respects MLton&#8217;s type checker is more powerful than other SML\r
37compilers, so there are programs that MLton accepts that are rejected\r
38by some other SML compilers. These kinds of programs fall into a few\r
39simple categories.</p></div>\r
40<div class="ulist"><ul>\r
41<li>\r
42<p>\r
43MLton resolves flexible record patterns using a larger context than\r
44many other SML compilers. For example, MLton accepts the\r
45following.\r
46</p>\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="p">...}</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">x</span><span class="w"></span>\r
49<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="p">{</span><span class="n">x</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">13</span><span class="p">,</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="s">&quot;foo&quot;</span><span class="p">}</span><span class="w"></span>\r
50</pre></div></div></div>\r
51</li>\r
52<li>\r
53<p>\r
54MLton uses as large a context as possible to resolve the type of\r
55variables constrained by the value restriction to be monotypes. For\r
56example, MLton accepts the following.\r
57</p>\r
58<div class="listingblock">\r
59<div class="content"><div class="highlight"><pre><span class="k">structure</span><span class="w"> </span><span class="n">S</span><span class="p">:</span><span class="w"></span>\r
60<span class="w"> </span><span class="k">sig</span><span class="w"></span>\r
61<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">int</span><span class="w"></span>\r
62<span class="w"> </span><span class="k">end</span><span class="w"> </span><span class="p">=</span><span class="w"></span>\r
63<span class="w"> </span><span class="k">struct</span><span class="w"></span>\r
64<span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="p">(</span><span class="k">fn</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="n">x</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="k">fn</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="n">y</span><span class="p">)</span><span class="w"></span>\r
65<span class="w"> </span><span class="k">end</span><span class="w"></span>\r
66</pre></div></div></div>\r
67</li>\r
68</ul></div>\r
69</div>\r
70</div>\r
71<div class="sect1">\r
72<h2 id="_type_error_messages">Type error messages</h2>\r
73<div class="sectionbody">\r
74<div class="paragraph"><p>To aid in the understanding of type errors, MLton&#8217;s type checker\r
75displays type errors differently than other SML compilers. In\r
76particular, when two types are different, it is important for the\r
77programmer to easily understand why they are different. So, MLton\r
78displays only the differences between two types that don&#8217;t match,\r
79using underscores for the parts that match. For example, if a\r
80function expects <span class="monospaced">real * int</span> but gets <span class="monospaced">real * real</span>, the type error\r
81message would look like</p></div>\r
82<div class="listingblock">\r
83<div class="content monospaced">\r
84<pre>expects: _ * [int]\r
85but got: _ * [real]</pre>\r
86</div></div>\r
87<div class="paragraph"><p>As another aid to spotting differences, MLton places brackets <span class="monospaced">[]</span>\r
88around the parts of the types that don&#8217;t match. A common situation is\r
89when a function receives a different number of arguments than it\r
90expects, in which case you might see an error like</p></div>\r
91<div class="listingblock">\r
92<div class="content monospaced">\r
93<pre>expects: [int * real]\r
94but got: [int * real * string]</pre>\r
95</div></div>\r
96<div class="paragraph"><p>The brackets make it easy to see that the problem is that the tuples\r
97have different numbers of components&#8201;&#8212;&#8201;not that the components don&#8217;t\r
98match. Contrast that with a case where a function receives the right\r
99number of arguments, but in the wrong order, in which case you might\r
100see an error like</p></div>\r
101<div class="listingblock">\r
102<div class="content monospaced">\r
103<pre>expects: [int] * [real]\r
104but got: [real] * [int]</pre>\r
105</div></div>\r
106<div class="paragraph"><p>Here the brackets make it easy to see that the components do not match.</p></div>\r
107<div class="paragraph"><p>We appreciate feedback on any type error messages that you find\r
108confusing, or suggestions you may have for improvements to error\r
109messages.</p></div>\r
110</div>\r
111</div>\r
112<div class="sect1">\r
113<h2 id="_the_shortest_most_recent_rule_for_type_names">The shortest/most-recent rule for type names</h2>\r
114<div class="sectionbody">\r
115<div class="paragraph"><p>In a type error message, MLton often has a number of choices in\r
116deciding what name to use for a type. For example, in the following\r
117type-incorrect program</p></div>\r
118<div class="listingblock">\r
119<div class="content"><div class="highlight"><pre><span class="k">type</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">int</span><span class="w"></span>\r
120<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">t</span><span class="p">)</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">x</span><span class="w"></span>\r
121<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="s">&quot;foo&quot;</span><span class="w"></span>\r
122</pre></div></div></div>\r
123<div class="paragraph"><p>MLton reports the error message</p></div>\r
124<div class="listingblock">\r
125<div class="content monospaced">\r
126<pre>Error: z.sml 3.9-3.15.\r
127 Function applied to incorrect argument.\r
128 expects: [t]\r
129 but got: [string]\r
130 in: f "foo"</pre>\r
131</div></div>\r
132<div class="paragraph"><p>MLton could have reported <span class="monospaced">expects: [int]</span> instead of <span class="monospaced">expects: [t]</span>.\r
133However, MLton uses the shortest/most-recent rule in order to decide\r
134what type name to display. This rule means that, at the point of the\r
135error, MLton first looks for the shortest name for a type in terms of\r
136number of structure identifiers (e.g. <span class="monospaced">foobar</span> is shorter than <span class="monospaced">A.t</span>).\r
137Next, if there are multiple names of the same length, then MLton uses\r
138the most recently defined name. It is this tiebreaker that causes\r
139MLton to prefer <span class="monospaced">t</span> to <span class="monospaced">int</span> in the above example.</p></div>\r
140<div class="paragraph"><p>In signature matching, most recently defined is not taken to include\r
141all of the definitions introduced by the structure (since the matching\r
142takes place outside the structure and before it is defined). For\r
143example, in the following type-incorrect program</p></div>\r
144<div class="listingblock">\r
145<div class="content"><div class="highlight"><pre><span class="k">structure</span><span class="w"> </span><span class="n">S</span><span class="p">:</span><span class="w"></span>\r
146<span class="w"> </span><span class="k">sig</span><span class="w"></span>\r
147<span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">x</span><span class="p">:</span><span class="w"> </span><span class="n">int</span><span class="w"></span>\r
148<span class="w"> </span><span class="k">end</span><span class="w"> </span><span class="p">=</span><span class="w"></span>\r
149<span class="w"> </span><span class="k">struct</span><span class="w"></span>\r
150<span class="w"> </span><span class="k">type</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">int</span><span class="w"></span>\r
151<span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="s">&quot;foo&quot;</span><span class="w"></span>\r
152<span class="w"> </span><span class="k">end</span><span class="w"></span>\r
153</pre></div></div></div>\r
154<div class="paragraph"><p>MLton reports the error message</p></div>\r
155<div class="listingblock">\r
156<div class="content monospaced">\r
157<pre>Error: z.sml 2.4-4.6.\r
158 Variable in structure disagrees with signature (type): x.\r
159 structure: val x: [string]\r
160 defn at: z.sml 7.11-7.11\r
161 signature: val x: [int]\r
162 spec at: z.sml 3.11-3.11</pre>\r
163</div></div>\r
164<div class="paragraph"><p>If there is a type that only exists inside the structure being\r
165matched, then the prefix <span class="monospaced">_str.</span> is used. For example, in the\r
166following type-incorrect program</p></div>\r
167<div class="listingblock">\r
168<div class="content"><div class="highlight"><pre><span class="k">structure</span><span class="w"> </span><span class="n">S</span><span class="p">:</span><span class="w"></span>\r
169<span class="w"> </span><span class="k">sig</span><span class="w"></span>\r
170<span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">x</span><span class="p">:</span><span class="w"> </span><span class="n">int</span><span class="w"></span>\r
171<span class="w"> </span><span class="k">end</span><span class="w"> </span><span class="p">=</span><span class="w"></span>\r
172<span class="w"> </span><span class="k">struct</span><span class="w"></span>\r
173<span class="w"> </span><span class="k">datatype</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">T</span><span class="w"></span>\r
174<span class="w"> </span><span class="k">val</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">T</span><span class="w"></span>\r
175<span class="w"> </span><span class="k">end</span><span class="w"></span>\r
176</pre></div></div></div>\r
177<div class="paragraph"><p>MLton reports the error message</p></div>\r
178<div class="listingblock">\r
179<div class="content monospaced">\r
180<pre>Error: z.sml 2.4-4.6.\r
181 Variable in structure disagrees with signature (type): x.\r
182 structure: val x: [_str.t]\r
183 defn at: z.sml 7.11-7.11\r
184 signature: val x: [int]\r
185 spec at: z.sml 3.11-3.11</pre>\r
186</div></div>\r
187<div class="paragraph"><p>in which the <span class="monospaced">[_str.t]</span> refers to the type defined in the structure.</p></div>\r
188</div>\r
189</div>\r
190</div>\r
191<div id="footnotes"><hr></div>\r
192<div id="footer">\r
193<div id="footer-text">\r
194</div>\r
195<div id="footer-badges">\r
196</div>\r
197</div>\r
198</body>\r
199</html>\r