
Am Montag, 17. Dezember 2007 19:26 schrieb Tim Chevalier:
On 12/17/07, Evan Laforge
wrote: I'm sure there's a trivial explanation for this, but here's something that I've always kind of wondered about: Given a single constructor type like "data X = X A B C" can't that be transformed into "newtype X = X (A, B, C)"? There must be some difference, because if there weren't we could transform all single constructor types that way, and dispense with newtype entirely.
Strictness. In newtype X = X A, the A field is strict. In data X = X A, the A field is lazy. So the compiler can't just turn all single-constructor "data" types into "newtypes".
Evan talked about data constructors with multiple fields, not with one single field.
(To generalize, if you were going to allow newtypes like "newtype X = X (A, B, C)", the tuple would be unboxed, and you'd have the same strictness/laziness distinction.)
This is not a generalization of what you talked about. Why should the tuple type be unboxed? Tuple types are boxed, meaning there is a difference between _|_ and (_|_,…,_|_). If you write newtype X = X (A, B, C) then X doesn’t add another level of indirection but the level of indirection introduced by the tuple constructor remains, of course. So you could write the above newtype declaration instead of data X = X A B C. _|_ would then be represented as X _|_ (equal to _|_) and X _|_ _|_ _|_ as X (_|_,_|_,_|_). Instead of pattern matching against X a b c, you would have to pattern match against X (a,b,c). So why not use the above newtype declaration instead of multi-field data declarations? One strong reason is that tuple types are itself algebraic data types which could be defined by data declarations if they wouldn’t use special syntax. So we would have to represent a tuple type by a newtype whose field type would be the tuple type we just want to represent.
[…]
Cheers, Tim
Best wishes, Wolfgang