[Haskell] Num is such a fat and greedy class

S.M.Kahrs S.M.Kahrs at kent.ac.uk
Mon Dec 11 09:40:03 EST 2006

> > let data Bar = ... in  ...
> >
> If you allow this you need to be very careful about type equality.   
> When is Bar equal to Bar?
> If it's inside a recursive function, does each invocation get its
> own Bar?  (In SML the answer is yes.) 

Not really.
In SML the answer used to be a clear "no", that is: in the 1990
definition. However, that proved to be a matter of type-unsoundness,
and Claudio Russo came up with an example that used this feature to
break the type system. Having said this, this was based on the way the
type system was defined in the language definition, the problem did not
show up in implementations (which therefore failed to implement the
language standard :-).

The problem was fixed in the 1997 language standard.
But there the answer isn't "yes" either, it is more like: "whatever it
is, you cannot tell", though technically it is still "no".

In the static semantics, a local datatype in SML is fresh.
However, this freshness is a static freshness, at compile time,
and every time the code is run the same "type name" (a uniqueness tag
for types) will be used: there is no run time type-checking, the type
name is generated once, at compile time.
However, that type name is not allowed to leak to the outside, i.e.
not only is the identifier Bar not visible outside, the type of the
value returned by the let-expression must not contain the type name
associated with Bar. Thus, if a let-expression with a local datatype is
evaluated twice, it does not really matter whether it uses the same or a
different type name because encapsulation ensures
that these type names do not interfere with each other in any way.

In a nutshell: local types are not worth the trouble they cause.

More information about the Haskell mailing list