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