Phil says:

| I think its vital that users know how to declare a new isomorphic
| datatype; it is not vital that they understand strictness declarations.
| Hence, I favor that
| 
|       newtype Age = Age Int
|       data Age = Age !Int
| 
| be synonyms, but that both syntaxes exist.
| 
| This is assuming I have understood Lennart correctly, and that
| 
|       foo (Age n) = (n, Age (n+1))
|       foo' a = (n, Age (n+1)) where (Age n) = a
| 
| are equivalent when Age is declared as a strict datatype. Unlike
| Sebastian or Simon, I believe it would be a disaster if for a newtype
| one had to distinguish these two definitions.

I agree that it is rather undesirable for them to differ.  If
someone had declared a *non-strict* verion like this:

        data Age = Age Int
        foo (Age n) = (n, Age (n+1))

(where foo is patently non-strict in n), and then just wanted to say "do
away with the Age constructor", I'd like it to be a one-line change (data
--> newtype), rather than also having to add a twiddle to every
pattern-match:

        foo ~(Age n) = (n, Age (n+1))

[which is eqiuvalent to using a where binding]

In effect, newtype could be explained as (a) a data decl with a !, and (b)
adding a ~ to every pattern match.

This is a hard one to call: which version actually requires least
explanation?!

Simon




Reply via email to