On Tue, 12 Sep 1995, Simon L Peyton Jones wrote:

> 
> 
> Phil writes:
> 
> | Make newtype equivalent to a datatype with one strict constructor.
> | Smaller language, more equivalences, simpler semantics, simpler
> | implementation.  An all around win!
> 
> I believe it would be a mistake to do this!  Consider:
> 
>       newtype Age = Age Int
>       
>       foo :: Age -> (Int, Age)
>       foo (Age n) = (n, Age (n+1))
> 
> Now, we intend that a value of type (Age Int) should be represented by
> an Int.  Thus, apart from the types involved, the following program should
> be equivalent:
> 
>       type Age' = Int
> 
>       foo' :: Age' -> (Int, Age')
>       foo' n = (n, n+1)

Is it really a good idea to extend the language simply to allow foo and 
foo' to be equivalent? The effect of foo' can still be achieved if Age is 
a strict data constructor:

        foo'' :: Age -> (Int, Age)
        foo'' a = (n, Age (n+1)) where (Age n) = a

and compilers are free (obliged?) to represent a value of type Age by an
Int. It might even be rather confusing if foo were not strict, given that
it appears to pattern match on its argument. (Of course, you could 
equally argue that it is confusing that

        case Foo undefined of Foo _ -> True = undefined

in a lazy language, but that can't be helped if strict constructors are 
allowed - unless some lexical distinction is introduced, eg strict 
constructor names must start with `!'.)

Why not keep things simple and, as Ryszard Kubiak suggests, abandon the
newtype syntax altogether? 

Sebastian Hunt



Reply via email to