Import Upstream version 20180207
[hcoop/debian/mlton.git] / doc / guide / src / TypeChecking.adoc
CommitLineData
7f918cf1
CE
1TypeChecking
2============
3
4MLton's type checker follows the <:DefinitionOfStandardML:Definition>
5closely, so you may find differences between MLton and other SML
6compilers that do not follow the Definition so closely. In
7particular, SML/NJ has many deviations from the Definition -- please
8see <:SMLNJDeviations:> for those that we are aware of.
9
10In some respects MLton's type checker is more powerful than other SML
11compilers, so there are programs that MLton accepts that are rejected
12by some other SML compilers. These kinds of programs fall into a few
13simple categories.
14
15* MLton resolves flexible record patterns using a larger context than
16many other SML compilers. For example, MLton accepts the
17following.
18+
19[source,sml]
20----
21fun f {x, ...} = x
22val _ = f {x = 13, y = "foo"}
23----
24
25* MLton uses as large a context as possible to resolve the type of
26variables constrained by the value restriction to be monotypes. For
27example, MLton accepts the following.
28+
29[source,sml]
30----
31structure S:
32 sig
33 val f: int -> int
34 end =
35 struct
36 val f = (fn x => x) (fn y => y)
37 end
38----
39
40
41== Type error messages ==
42
43To aid in the understanding of type errors, MLton's type checker
44displays type errors differently than other SML compilers. In
45particular, when two types are different, it is important for the
46programmer to easily understand why they are different. So, MLton
47displays only the differences between two types that don't match,
48using underscores for the parts that match. For example, if a
49function expects `real * int` but gets `real * real`, the type error
50message would look like
51
52----
53expects: _ * [int]
54but got: _ * [real]
55----
56
57As another aid to spotting differences, MLton places brackets `[]`
58around the parts of the types that don't match. A common situation is
59when a function receives a different number of arguments than it
60expects, in which case you might see an error like
61
62----
63expects: [int * real]
64but got: [int * real * string]
65----
66
67The brackets make it easy to see that the problem is that the tuples
68have different numbers of components -- not that the components don't
69match. Contrast that with a case where a function receives the right
70number of arguments, but in the wrong order, in which case you might
71see an error like
72
73----
74expects: [int] * [real]
75but got: [real] * [int]
76----
77
78Here the brackets make it easy to see that the components do not match.
79
80We appreciate feedback on any type error messages that you find
81confusing, or suggestions you may have for improvements to error
82messages.
83
84
85== The shortest/most-recent rule for type names ==
86
87In a type error message, MLton often has a number of choices in
88deciding what name to use for a type. For example, in the following
89type-incorrect program
90
91[source,sml]
92----
93type t = int
94fun f (x: t) = x
95val _ = f "foo"
96----
97
98MLton reports the error message
99
100----
101Error: z.sml 3.9-3.15.
102 Function applied to incorrect argument.
103 expects: [t]
104 but got: [string]
105 in: f "foo"
106----
107
108MLton could have reported `expects: [int]` instead of `expects: [t]`.
109However, MLton uses the shortest/most-recent rule in order to decide
110what type name to display. This rule means that, at the point of the
111error, MLton first looks for the shortest name for a type in terms of
112number of structure identifiers (e.g. `foobar` is shorter than `A.t`).
113Next, if there are multiple names of the same length, then MLton uses
114the most recently defined name. It is this tiebreaker that causes
115MLton to prefer `t` to `int` in the above example.
116
117In signature matching, most recently defined is not taken to include
118all of the definitions introduced by the structure (since the matching
119takes place outside the structure and before it is defined). For
120example, in the following type-incorrect program
121
122[source,sml]
123----
124structure S:
125 sig
126 val x: int
127 end =
128 struct
129 type t = int
130 val x = "foo"
131 end
132----
133
134MLton reports the error message
135
136----
137Error: z.sml 2.4-4.6.
138 Variable in structure disagrees with signature (type): x.
139 structure: val x: [string]
140 defn at: z.sml 7.11-7.11
141 signature: val x: [int]
142 spec at: z.sml 3.11-3.11
143----
144
145If there is a type that only exists inside the structure being
146matched, then the prefix `_str.` is used. For example, in the
147following type-incorrect program
148
149[source,sml]
150----
151structure S:
152 sig
153 val x: int
154 end =
155 struct
156 datatype t = T
157 val x = T
158 end
159----
160
161MLton reports the error message
162
163----
164Error: z.sml 2.4-4.6.
165 Variable in structure disagrees with signature (type): x.
166 structure: val x: [_str.t]
167 defn at: z.sml 7.11-7.11
168 signature: val x: [int]
169 spec at: z.sml 3.11-3.11
170----
171
172in which the `[_str.t]` refers to the type defined in the structure.