
On Mon, Oct 6, 2008 at 3:30 PM, Arnar Birgisson
"undefined" is evaluated to see if it matches the constructor "A". But we don't even get to check, because undefined throws an exception during its evaluation.
In the "tb" case, (B x) always matches because B is a newtype. x gets bound to undefined, but never evaluated.
And this happens because data values are basically pattern matched at run-time but newtype values are matched at compile-time, effectively turning tb into an Int -> Bool function?
Yep, that's exactly it.
That explains pretty well why newtype can have only one constructor.
I never thought of it that way, but yes, it really does! Also, you can get the same behavior out of "ta" if you write it like this: ta ~(A x) = True The translation looks something like this: f ~(A x) = e => f a = e where x = case a of (A v) -> v -- a,v fresh variables not mentioned in e (or, equivalently) f a = let (A x) = a in e -- "a" some fresh variable not mentioned in e This delays the pattern-matching (and thus, the evaluation of "a") lazily until "x" is demanded, at which point "a" might throw an exception or infinite loop, or, if the type has more than one constructor, fail to pattern match (which also throws an exception). If "x" is never demanded then neither is "a". -- ryan