Feuer [email protected]
Tue, 15 Jan 2002 04:31:51 -0800

I know what you mean.  However, if you look at it,
data Empty1 a = E1
is a datatype with one constructor, and that constructor takes no arguments.
So this is in fact a "phantom" unit type.
newtype Empty2 a = E2 ()
is in fact better than
data EmptyBad a = EBad ()
because the constructor E will be optimised away, and the type will be share
the representation of the unit type ().  However, I don't see why Empty1 and
Empty2 would differ in any way at all...  In any reasonable implementation,
they would have the same internal representation, right?

data Pair1 v w a = P1 (v a) (w a)
is just a tuple type.  It should be exactly the same as
newtype Pair2 v w a = P2 (v a, w a)

If someone can explain why they would be different, I'm all ears.

By the way, I don't understand why Haskell98 provides both strictness flags
and newtype declarations.... it seems to me that
newtype M [a1 a2 ....] = MC (...)
should be exactly the same as
data N [b1 b2 ....] = NC !(...)
If I'm not mistaken, any compiler too dumb to notice a datatype with only one
constructor strict in its one argument is too dumb to use.

Ketil's local user wrote:

> Feuer <[email protected]> asks about:
> > newtype Empty a = E ()
> vs.
> > data Empty a = E
> and
> > newtype Pair v w a = P (v a, w a)
> vs.
> > data Pair v w a = P (v a) (w a)
> > I was wondering if anyone on this list knew of any reasons the types he
> > chose would be more efficient than mine....
> When recently reading the GHC docs, the chapter about profiling, I
> think, I came across something about this.  From Chapter 6:
> | Newtypes are better than datatypes:
> |
> |    If your datatype has a single constructor with a single field,
> | use a newtype declaration instead of a data declaration. The newtype
> | will be optimised away in most cases
> -kzm
> --
> If I haven't seen further, it is by standing in the footprints of giants