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: 
Simple version for folks obsessed with bullet lists (failed to find one, so have to write it by myself):

**data** - creates new algebraic type with value constructors

* Can have several value constructors
* Value constructors are lazy
* Values can have several fields
* Affects both compilation and runtime, have runtime overhead
* Created type is a distinct new type
* Can have its own type class instances
* When pattern matching against value constructors, WILL be evaluated at least to weak head normal form (WHNF) \*
* Used to create new data type (example: Address { zip :: String, street :: String } )

**newtype** - creates new “decorating” type with value constructor

* Can have only one value constructor
* Value constructor is strict
* Value can have only one field
* Affects only compilation, no runtime overhead
* Created type is a distinct new type
* Can have its own type class instances
* When pattern matching against value constructor, CAN be not evaluated at all \*
* Used to create higher level concept based on existing type with distinct set of supported operations or that is not interchangeable with original type (example: Meter, Cm, Feet is Double)

**type** - creates an alternative name (synonym) for a type (like typedef in C)

* No value constructors
* No fields
* Affects only compilation, no runtime overhead
* No new type is created (only a new name for existing type)
* Can NOT have its own type class instances
* When pattern matching against data constructor, behaves the same as original type
* Used to create higher level concept based on existing type with the same set of supported operations (example: String is [Char])

[\*] On pattern matching laziness:

```
data DataBox a = DataBox Int
newtype NewtypeBox a = NewtypeBox Int

dataMatcher :: DataBox -> String
dataMatcher (DataBox _) = "data"

newtypeMatcher :: NewtypeBox -> String 
newtypeMatcher (NewtypeBox _) = "newtype"

ghci> dataMatcher undefined
"*** Exception: Prelude.undefined

ghci> newtypeMatcher undefined
“newtype"

```
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.