DefineTypeBeforeUse =================== <:StandardML: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`. [source,sml] ---- 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`. [source,sml] ---- 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 ()) () ----