Makarius wrote:
The paragraph says "This can be included within the abstract type or outside it." According to what you have explained to me earlier, it actually depends if opaque signature matching is involved.
Here is a refined example:
structure Test :> sig type T val x: T exception Err of T val bad: unit -> 'a end = struct
datatype T = T of int;
val x = T 42;
exception Err of T;
fun bad () = raise Err x;
val _ = PolyML.addPrettyPrinter (fn _ => fn _ => fn (_: T) => PolyML.PrettyString "<inner>");
end;
val _ = PolyML.addPrettyPrinter (fn _ => fn _ => fn (_: Test.T) => PolyML.PrettyString "<outer>");
Now the behaviour is like this:
ML> Test.x; val it = <outer> : Test.T ML> Test.bad (); Exception- Err of <inner> raised
Using plain ":" instead of ":>" above will produce "<outer>" in both cases.
I can see your point. To be honest, when I think of an abstract type I think of the abstype construction rather than opaque signature matching. Using abstype here does print "<outer>" in both cases. I should make that more explicit in the FAQ.
There are several things going on here with the opaque matching example. Using an opaque match creates a different type for the purposes of the pretty printer. That's important if the implementing type is something like "int" which already has a pretty printer. In that case it's necessary to install the pretty printer outside the opaque signature otherwise it would over-write the existing pretty printer. If a transparent signature is used types are treated the same for the pretty printer so the outer pretty printer replaces the inner one.
An area that you have brought up which maybe needs to be looked at is the interaction between pretty printers and exceptions. An exception constructor "captures" the pretty print function for the type at its declaration. It doesn't change with the opaque matching. Not only does
Test.bad()
Exception- Err of <inner> raised but also
raise Test.Err Test.x;
The type of (it) contains a free type variable. Setting it to a unique monotype. Exception- Err of <inner> raised
That's certainly not intuitive and even if the former might make a bit of sense the latter is probably confusing.
David