signature TYPES = sig eqtype unique datatype ty = INT | STRING | RECORD of (Symbol.symbol * ty) list * unique | ARRAY of ty * unique | NIL | UNIT | NAME of Symbol.symbol * ty option ref val equal: ty * ty -> bool val ty2str: ty -> string end structure Types: TYPES = struct type unique = unit ref datatype ty = INT | STRING | RECORD of (Symbol.symbol * ty) list * unique | ARRAY of ty * unique | NIL | UNIT | NAME of Symbol.symbol * ty option ref fun equal (INT, INT) = true | equal (STRING, STRING) = true | equal (RECORD (_, u), RECORD (_, u')) = (u = u') | equal (ARRAY (_, u), ARRAY (_, u')) = (u = u') | equal (NIL, NIL) = true | equal (UNIT, UNIT) = true | equal (NAME (_, rot), ty') = (case !rot of SOME ty => equal (ty, ty')) | equal (ty, NAME (_, rot')) = (case !rot' of SOME ty' => equal (ty, ty')) | equal (RECORD _, NIL) = true | equal (NIL, RECORD _) = true | equal (_, _) = false fun ty2str INT = "int" | ty2str STRING = "string" | ty2str (RECORD (idtys, _)) = "{" ^ idtys2str idtys ^ "}" | ty2str (ARRAY (ty, _)) = "array(" ^ ty2str ty ^ ")" | ty2str NIL = "nil" | ty2str UNIT = "unit" | ty2str (NAME (id, _)) = Symbol.name id and idty2str (id, ty) = Symbol.name id ^ ": " ^ ty2str ty and idtys2str [] = "" | idtys2str [(id, ty)] = idty2str (id, ty) | idtys2str (idty :: idtys) = idty2str idty ^ ", " ^ idtys2str idtys end