newtype pattern matching

Marcin 'Qrczak' Kowalczyk qrczak@knm.org.pl
Fri, 25 Jan 2002 21:51:23 +0000 (UTC)


25 Jan 2002 08:00:24 +0100, Martin Norbäck <d95mback@dtek.chalmers.se> pisze:

> newtype T1 = C1 Bool
> data    T2 = C2 !Bool
> 
> the difference is that the constructor C1 does not exist, so only the
> following values exist for T1:
> 
> C1 True  (which is the represented as True)
> C1 False (which is the represented as False)
> C1 _|_   (which is represented as non-termination or error)
> 
> however, for T2, another value exist, namely _|_.

But it's the same as C2 _|_. These types have the same number of
values and T2 could be represented isomorphically to Bool too.
The only difference between T1 and T2 is that

    case x of
        C2 _ -> ...

causes the evaluation of x (and thus the Bool inside - because it was
"strictly" tied to the constructor!). It's the same as   x `seq` ...
or as   the_Bool_inside `seq` ...

The side effect of using data with a strict argument instead of
newtype is that

    f' (C2 x) (C2 y) = C2 (f x y)

unexpectedly becomes strict in both arguments, and we would have
to write

    f' x y = C2 (f (case x of C2 x' -> x')
                   (case y of C2 y' -> y'))

in the general case where we want to preserve strictness and don't
want to analyze it ourselves. Newtypes allow to use the convenient
syntax of pattern matching on the lhs.

-- 
 __("<  Marcin Kowalczyk * qrczak@knm.org.pl http://qrczak.ids.net.pl/
 \__/
  ^^
QRCZAK