PolyML.addPrettyPrinter checks its printArgTypes parameter carefully when you are installing a pretty-printer for a polymorphic type. As far as I can see it guarantees type security for polymorphic types.
However, when you install a pretty-printer for a monomorphic type, the parameter isn't checked at all. E.g., the following code doesn't result in any error messages and ends by crashing poly.
datatype MONO = Mono of int;
fun pp_mono1 _ (i : int) (Mono j) = ( PolyML.PrettyString (Int.toString (i + j)) );
PolyML.addPrettyPrinter pp_mono1;
Mono 42; (* Prints "val it = 42: MONO" - apparently i was 0 *)
fun pp_mono2 _ (r : int ref) (Mono _) = ( PolyML.PrettyString (Int.toString (!r)) );
PolyML.addPrettyPrinter pp_mono2;
Mono 42; (* Crashes *)
Shouldn't processArgTypes be required to have type unit when defining a pretty-printer for a monotype? The patch below implements this check and tries to improve the error message (which is already a bit misleading if you get something wrong for a type with more than one parameter).
Regards,
Rob.
diff --git a/mlsource/MLCompiler/VALUE_OPS.ML b/mlsource/MLCompiler/VALUE_OPS.ML index 1535d4f..9e00f0d 100644 --- a/mlsource/MLCompiler/VALUE_OPS.ML +++ b/mlsource/MLCompiler/VALUE_OPS.ML @@ -958,8 +958,8 @@ struct val typeVars = List.tabulate(arity, fn _ => mkTypeVar (0, false, true, false)) val tupleType = case typeVars of - [] => (* No arg so we can have anything here. *) - mkTypeVar (generalisable, false, false, false) + [] => (* No arg so must have unit. *) + unitType | [arg] => mkFn arg (* Just a single function. *) | args => mkProductType(List.map mkFn args) val addPPType = mkFunctionType(argPrints, mkFunctionType(installType, pretty)) @@ -970,7 +970,7 @@ struct in checkPPType(addPPType, testType, "addPrettyPrint", lex, loc, fn () => - PrettyString "addPrettyPrint element functions must have type 'a * int -> pretty") + PrettyString "addPrettyPrint element functions must have type 'a * int -> pretty, 'b * int -> pretty, ... with one function for each type parameter") end;
(* Only report the error when the function is run. Because addPrettyPrint is