Question: It seems that a `newtype` definition is just a `data` definition that obeys some restrictions (e.g., only one constructor), and that due to these restrictions the runtime system can handle `newtype`s more efficiently. And the handling of pattern matching for undefined values is slightly different. 

But suppose Haskell would only knew `data` definitions, no `newtype`s: couldn't the compiler find out for itself whether a given data definition obeys these restrictions, and automatically treat it more efficiently? 

I'm sure I'm missing out on something, there must be some deeper reason for this.

Answer: 
Both `newtype` and the single-constructor `data` introduce a single value constructor, but the value constructor introduced by `newtype` is strict and the value constructor introduced by `data` is lazy. So if you have

```
data D = D Int
newtype N = N Int

```

Then `N undefined` is equivalent to `undefined` and causes an error when evaluated. But `D undefined` is *not* equivalent to `undefined`, and it can be evaluated as long as you don't try to peek inside.

> 
> Couldn't the compiler handle this for itself.
> 
> 
> 

No, not really—this is a case where as the programmer you get to decide whether the constructor is strict or lazy. To understand when and how to make constructors strict or lazy, you have to have a much better understanding of lazy evaluation than I do. I stick to the idea in the Report, namely that `newtype` is there for you to rename an existing type, like having several different incompatible kinds of measurements:

```
newtype Feet = Feet Double
newtype Cm   = Cm   Double

```

both behave exactly like `Double` at run time, but the compiler promises not to let you confuse them.
Off the top of my head; data declarations use lazy evaluation in access and storage of their "members", whereas newtype does not. Newtype also strips away all previous type instances from its components, effectively hiding its implementation; whereas data leaves the implementation open.

I tend to use newtype's when avoiding boilerplate code in complex data types where I don't necessarily need access to the internals when using them. This speeds up both compilation and execution, and reduces code complexity where the new type is used.

When first reading about this I found [this chapter](http://www.haskell.org/tutorial/moretypes.html) of a Gentle Introduction to Haskell rather intuitive.