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 1.1. Type escapes the scope of its definition at z.sml 2.10. type: t 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.1. Unable to locally determine type of variable: r. type: ??? option ref in: val r = ref NONE Error: z.sml 1.1. Type escapes the scope of its definition at z.sml 2.17. type: t in: val r = ref NONE
Warning- in 'z.sml', line 13. The type of (r) contains a free type variable. Setting it to a unique monotype. Error- in 'z.sml', line 5. Type error in function application. Function: := : _a option ref * _a option -> unit Argument: (r, SOME x) : _a option ref * t option Reason: Can't unify _a (*Constructed from a free type variable.*) with t (Different type constructors) Found near r := SOME x Error- in 'z.sml', line 12. Type error in function application. Function: S1.get () : _a Argument: () : unit Reason: Value being applied does not have a function type Found near S1.get () ()