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