25 Jan 2002 08:00:24 +0100, Martin Norbäck <[EMAIL PROTECTED]> 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 * [EMAIL PROTECTED] http://qrczak.ids.net.pl/ \__/ ^^ QRCZAK _______________________________________________ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell