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


_______________________________________________
polyml mailing list
[email protected]
http://lists.inf.ed.ac.uk/mailman/listinfo/polyml

Reply via email to