On 11/08/2013 21:27, Phil Clayton wrote:
11/08/13 16:06, Rob Arthan wrote:
Poly/ML seems to be a little inconsistent about when it uses type names supplied by the user to abbreviate types as shown in the following transcript:
type COMPLEX = {re : real, im : real};
type COMPLEX = {im: real, re: real}
val unity : COMPLEX = {re = 1.0, im = 0.0};
val unity = {im = 0.0, re = 1.0}: COMPLEX
fun negate ({re, im} : COMPLEX) : COMPLEX = {re = ~re, im = ~im};
val negate = fn: COMPLEX -> {im: real, re: real}
I often find myself putting a type constraint on the right-hand side expression so that Poly/ML prints back the type abbreviation, i.e.
fun negate ({re, im} : COMPLEX) = {re = ~re, im = ~im} : COMPLEX;
I presume that a type annotation on the left-hand side isn't used because it is optional. However, it would be nice if it was.
I seem to recall when looking into some rather strange examples that the Definition of Standard ML assumes that all type abbreviations are removed before unification. Poly/ML tries to hang on to type abbreviations when it can to help with printing but the primary aim is to get type checking correct.
I've had a look at this particular case and committed a change. It's all to do with which type is used to construct the function type for the result. Previously it used the type of the expression. I've changed it to use the type of the constraint if it's present. The two are unified to check that the constraint is valid; it's just how they're printed that differs.
Regards, David