Standard ML requires types to be defined before they are
used. Because of type inference, the use of a type can be implicit;
hence, this requirement is more subtle than it might appear. For
example, the following program is not type correct, because the type
of r is t option ref, but t is defined after r.
val r = ref NONE
datatype t = A | B
val () = r := SOME A
MLton reports the following error, indicating that the type defined on line 2 is used on line 1.
Error: z.sml 3.10-3.20.
Function applied to incorrect argument.
expects: _ * [???] option
but got: _ * [t] option
in: := (r, SOME A)
note: type would escape its scope: t
escape from: z.sml 2.10-2.10
escape to: z.sml 1.1-1.16
Warning: z.sml 1.5-1.5.
Type of variable was not inferred and could not be generalized: r.
type: ??? option ref
in: val r = ref NONE
While the above example is benign, the following example shows how to
cast an integer to a function by (implicitly) using a type before it
is defined. In the example, the ref cell r is of type
t option ref, where t is defined after r, as a parameter to
functor F.
val r = ref NONE
functor F (type t
val x: t) =
struct
val () = r := SOME x
fun get () = valOf (!r)
end
structure S1 = F (type t = unit -> unit
val x = fn () => ())
structure S2 = F (type t = int
val x = 13)
val () = S1.get () ()
MLton reports the following error.
Warning: z.sml 1.5-1.5.
Type of variable was not inferred and could not be generalized: r.
type: ??? option ref
in: val r = ref NONE
Error: z.sml 5.16-5.26.
Function applied to incorrect argument.
expects: _ * [???] option
but got: _ * [t] option
in: := (r, SOME x)
note: type would escape its scope: t
escape from: z.sml 2.17-2.17
escape to: z.sml 1.1-1.16
Warning: z.sml 6.11-6.13.
Type of variable was not inferred and could not be generalized: get.
type: unit -> ???
in: fun get () = (valOf (! r))
Error: z.sml 12.10-12.18.
Function not of arrow type.
function: [unit]
in: (S1.get ()) ()