
By the way, I don't understand why Haskell98 provides both strictness flags and newtype declarations.... it seems to me that newtype M [a1 a2 ....] = MC (...) should be exactly the same as data N [b1 b2 ....] = NC !(...)
The Haskell report (in the "Datatype Renamings" section, 4.2.3, -- the one on newtype) explains the difference. Translating some of the examples there to your names, with
newtype M = M Int m (M i) = 42 data N = N !Int n (N i) = 42
we get Main> m undefined 42 but Main> n undefined *** Exception: Prelude.undefined mike

Well, I guess I was wrong about this. I was confused by the place where the Haskell Report says: Unlike algebraic datatypes, the newtype constructor N is unlifted, so that N _|_ is the same as _|_. What I didn't realize was that matching against N is irrefutable. What I still don't understand is _why_ it is irrefutable. How (if at all) does this make them more efficient? In particular, it seems it would be possible to simulate the newtype with a datatype: The report says that if data D2=D2 !Int newtype N = N Int d2 (D2 i) = 42 n (N i) = 42 then d2 _|_ = _|_ d2 (D2 _|_) = _|_ n _|_ = 42 n (N_|_) = 42 If d2 were rewritten d2' ~(D2 i) = 42 then it would act just like n. I guess the question is whether the code for d2' is as efficient as the code for n. I don't see why it wouldn't be, but of course I could be wrong.
participants (2)
-
Feuer
-
Mike Gunter