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