
Malcolm Wallace wrote:
Matthias Fischmann
wrote: No, your Fin type can also hold infinite values.
let q = FinCons 3 q in case q of FinCons i _ -> i ==> _|_
does that contradict, or did i just not understand what you are saying?
That may be the result in ghc, but nhc98 gives the answer 3.
It is not entirely clear which implementation is correct. The Language Report has little enough to say about strict components of data structures - a single paragraph in 4.2.1. It defines them in terms of the strict application operator ($!), thus ultimately in terms of seq, and as far as I can see, nhc98 is perfectly compliant here.
The definition of seq is seq _|_ b = _|_ seq a b = b, if a/= _|_
In the circular expression let q = FinCons 3 q in q it is clear that the second component of the FinCons constructor is not _|_ (it has at least a FinCons constructor), and therefore it does not matter what its full unfolding is.
The translation given in the language report says this expression is equivalent to let q = (\x1 x2 -> (( FinCons' $ x1) $! x2) ) 3 q in q (where FinCons' is a "lazy" constructor) in terms of seq let q = (\x1 x2 -> x2 `seq` ( FinCons' x1 x2 ) ) 3 q in q this evaluates to let q = (q `seq` ( FinCons' 3) ) in q hence on top-level q is rather a seq-expression than a constructor-expression ;-) Regards, David