[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Haskell 1.3 (newtype)



Resent-Message-Id: <199509131418.QAA17457@animal.cs.chalmers.se>
From: wadler@dcs.gla.ac.uk
Subject: Re: Haskell 1.3 (newtype)
Date: Wed, 13 Sep 95 15:13:39 BST
To: augustss, simonpj@dcs.gla.ac.uk, haskell@dcs.gla.ac.uk
Old-Resent-From: haskell-request@dcs.gla.ac.uk
Errors-To: haskell-request@dcs.gla.ac.uk
Approved: haskell@dcs.gla.ac.uk
Resent-Date:  Wed, 13 Sep 1995 15:14:24 +0100
Resent-From: kh@dcs.gla.ac.uk
Resent-To: haskell-list-dist@dcs.gla.ac.uk


Well, I'm glad to see I provoked some discussion!

Simon writes:

   Lennart writes:
   
   | So if we had
   | 
   | 	data Age = Age !Int
   | 	foo (Age n) = (n, Age (n+1))
   | 
   | it would translate to
   | 
   |  	foo (MakeAge n) = (n, seq MakeAge (n+1))
   | 
   | [makeAge is the "real" constructor of Age]
   
   Indeed, the (seq MakeAge (n+1) isn't eval'd till the second
   component of the pair is.  But my point was rather that foo
   evaluates its argument (MakeAge n), and hence n, as part of its
   pattern matching.  Hence foo is strict in n.

Why should foo evaluate its argument?  It sounds to me like
Lennart is right, and I should not have let Simon lead me astray!

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.

Cheers,  -- P