| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 
 | <!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="generator" content="AsciiDoc 8.6.8">
<title>TypeChecking</title>
<link rel="stylesheet" href="./asciidoc.css" type="text/css">
<link rel="stylesheet" href="./pygments.css" type="text/css">
<script type="text/javascript" src="./asciidoc.js"></script>
<script type="text/javascript">
/*<![CDATA[*/
asciidoc.install();
/*]]>*/
</script>
<link rel="stylesheet" href="./mlton.css" type="text/css"/>
</head>
<body class="article">
<div id="banner">
<div id="banner-home">
<a href="./Home">MLton 20130715</a>
</div>
</div>
<div id="header">
<h1>TypeChecking</h1>
</div>
<div id="content">
<div id="preamble">
<div class="sectionbody">
<div class="paragraph"><p>MLton’s type checker follows the <a href="DefinitionOfStandardML">Definition</a>
closely, so you may find differences between MLton and other SML
compilers that do not follow the Definition so closely.  In
particular, SML/NJ has many deviations from the Definition — please
see <a href="SMLNJDeviations">SMLNJDeviations</a> for those that we are aware of.</p></div>
<div class="paragraph"><p>In some respects MLton’s type checker is more powerful than other SML
compilers, so there are programs that MLton accepts that are rejected
by some other SML compilers.  These kinds of programs fall into a few
simple categories.</p></div>
<div class="ulist"><ul>
<li>
<p>
MLton resolves flexible record patterns using a larger context than
many other SML compilers.  For example, MLton accepts the
following.
</p>
<div class="listingblock">
<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>
<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">"foo"</span><span class="p">}</span><span class="w"></span>
</pre></div></div></div>
</li>
<li>
<p>
MLton uses as large a context as possible to resolve the type of
variables constrained by the value restriction to be monotypes.  For
example, MLton accepts the following.
</p>
<div class="listingblock">
<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>
<span class="w">   </span><span class="k">sig</span><span class="w"></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">-></span><span class="w"> </span><span class="n">int</span><span class="w"></span>
<span class="w">   </span><span class="k">end</span><span class="w"> </span><span class="p">=</span><span class="w"></span>
<span class="w">   </span><span class="k">struct</span><span class="w"></span>
<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">=></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">=></span><span class="w"> </span><span class="n">y</span><span class="p">)</span><span class="w"></span>
<span class="w">   </span><span class="k">end</span><span class="w"></span>
</pre></div></div></div>
</li>
</ul></div>
</div>
</div>
<div class="sect1">
<h2 id="_type_error_messages">Type error messages</h2>
<div class="sectionbody">
<div class="paragraph"><p>To aid in the understanding of type errors, MLton’s type checker
displays type errors differently than other SML compilers.  In
particular, when two types are different, it is important for the
programmer to easily understand why they are different.  So, MLton
displays only the differences between two types that don’t match,
using underscores for the parts that match.  For example, if a
function expects <span class="monospaced">real * int</span> but gets <span class="monospaced">real * real</span>, the type error
message would look like</p></div>
<div class="listingblock">
<div class="content monospaced">
<pre>expects: _ * [int]
but got: _ * [real]</pre>
</div></div>
<div class="paragraph"><p>As another aid to spotting differences, MLton places brackets <span class="monospaced">[]</span>
around the parts of the types that don’t match.  A common situation is
when a function receives a different number of arguments than it
expects, in which case you might see an error like</p></div>
<div class="listingblock">
<div class="content monospaced">
<pre>expects: [int * real]
but got: [int * real * string]</pre>
</div></div>
<div class="paragraph"><p>The brackets make it easy to see that the problem is that the tuples
have different numbers of components — not that the components don’t
match.  Contrast that with a case where a function receives the right
number of arguments, but in the wrong order, in which case you might
see an error like</p></div>
<div class="listingblock">
<div class="content monospaced">
<pre>expects: [int] * [real]
but got: [real] * [int]</pre>
</div></div>
<div class="paragraph"><p>Here the brackets make it easy to see that the components do not match.</p></div>
<div class="paragraph"><p>We appreciate feedback on any type error messages that you find
confusing, or suggestions you may have for improvements to error
messages.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_the_shortest_most_recent_rule_for_type_names">The shortest/most-recent rule for type names</h2>
<div class="sectionbody">
<div class="paragraph"><p>In a type error message, MLton often has a number of choices in
deciding what name to use for a type.  For example, in the following
type-incorrect program</p></div>
<div class="listingblock">
<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>
<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>
<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">"foo"</span><span class="w"></span>
</pre></div></div></div>
<div class="paragraph"><p>MLton reports the error message</p></div>
<div class="listingblock">
<div class="content monospaced">
<pre>Error: z.sml 3.9.
  Function applied to incorrect argument.
    expects: [t]
    but got: [string]
    in: f "foo"</pre>
</div></div>
<div class="paragraph"><p>MLton could have reported <span class="monospaced">expects: [int]</span> instead of <span class="monospaced">expects: [t]</span>.
However, MLton uses the shortest/most-recent rule in order to decide
what type name to display.  This rule means that, at the point of the
error, MLton first looks for the shortest name for a type in terms of
number of structure identifiers (e.g. <span class="monospaced">foobar</span> is shorter than <span class="monospaced">A.t</span>).
Next, if there are multiple names of the same length, then MLton uses
the most recently defined name.  It is this tiebreaker that causes
MLton to prefer <span class="monospaced">t</span> to <span class="monospaced">int</span> in the above example.</p></div>
<div class="paragraph"><p>In signature matching, most recently defined is taken to include all
of the definitions introduced by the structure.  For example</p></div>
<div class="listingblock">
<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>
<span class="w">   </span><span class="k">sig</span><span class="w"></span>
<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>
<span class="w">   </span><span class="k">end</span><span class="w"> </span><span class="p">=</span><span class="w"></span>
<span class="w">   </span><span class="k">struct</span><span class="w"></span>
<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>
<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">"foo"</span><span class="w"></span>
<span class="w">   </span><span class="k">end</span><span class="w"></span>
</pre></div></div></div>
<div class="paragraph"><p>MLton reports the error message</p></div>
<div class="listingblock">
<div class="content monospaced">
<pre>Error: z.sml 2.4.
  Variable type in structure disagrees with signature.
    variable: x
    structure: [string]
    signature: [t]</pre>
</div></div>
<div class="paragraph"><p>in which the <span class="monospaced">[t]</span> refers to the type defined in the structure, since
that is more recent than the definition of <span class="monospaced">int</span>.</p></div>
<div class="paragraph"><p>In signatures with type equations, this can be somewhat confusing.
For example.</p></div>
<div class="listingblock">
<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>
<span class="w">   </span><span class="k">sig</span><span class="w"></span>
<span class="w">      </span><span class="k">type</span><span class="w"> </span><span class="n">t</span><span class="w"></span>
<span class="w">      </span><span class="k">type</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">t</span><span class="w"></span>
<span class="w">   </span><span class="k">end</span><span class="w"> </span><span class="p">=</span><span class="w"></span>
<span class="w">   </span><span class="k">struct</span><span class="w"></span>
<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>
<span class="w">      </span><span class="k">type</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">char</span><span class="w"></span>
<span class="w">   </span><span class="k">end</span><span class="w"></span>
</pre></div></div></div>
<div class="paragraph"><p>MLton reports the error message</p></div>
<div class="listingblock">
<div class="content monospaced">
<pre>Error: z.sml 2.4.
  Type definition in structure disagrees with signature.
    type: u
    structure: [u]
    signature: [t]</pre>
</div></div>
<div class="paragraph"><p>This error reflects the fact that the signature requires type <span class="monospaced">u</span> to
equal <span class="monospaced">t</span>, but that in the structure, <span class="monospaced">u</span> is defined to be <span class="monospaced">char</span>,
whose most-recent name is <span class="monospaced">u</span>, while the signature requires <span class="monospaced">u</span> to be
<span class="monospaced">int</span>, whose most-recent name is <span class="monospaced">t</span>.</p></div>
</div>
</div>
</div>
<div id="footnotes"><hr></div>
<div id="footer">
<div id="footer-text">
</div>
<div id="footer-badges">
</div>
</div>
</body>
</html>
 |