
2009/5/28 Petr Pudlak
Hi Ryan, thanks for a nice and thorough explanation. I had trouble understanding the section of the tutorial as well. Maybe it would deserve to rewrite to something a bit simpler?
Anyhow, I'd like to ask: Is there a reason for which pattern matching for single-constructor data types isn't lazy by default? For example, why do I have to write
weird ~(x,y) = (1,x) crazy = weird crazy
when the compiler knows that the type (x,y) has just the single constructor, and could automatically introduce the additional laziness without any risk?
I think this is really two questions: 1) Why can't the /compiler/ add extra laziness automatically? Because it's not semantics preserving: weird (x, y) = (1, x) lazyWeird ~(x, y) = (1, x) weird undefined = undefined lazyWeird undefined = (1, undefined) Of course, it's arguable as to whether turning non-terminating programs into terminating ones is really that big of a deal. In fact, some transformations in GHC already make this kind of change for optimization purposes (albeit only to things of function type, where the waters are murkier). Even if it were semantics preserving, making things MORE lazy is not likely to lead to performance improvement, so I doubt the compiler would want to do this. 2) Why isn't product pattern matching lazy by default in Haskell? I can't give a definitive answer, but I suspect that the reason is that the Haskell design team didn't want adding an extra constructor to your type definition to change the semantics of all the pattern matches in your program. Seems pretty sensible to me :-) Cheers, Max