
On Fri, Jul 13, 2007 at 04:29:12PM -0700, Michael Vanier wrote:
Albert,
Thanks for the very detailed reply! That's the great thing about this mailing list.
I find your description of seq somewhat disturbing. Is this behavior documented in the API? I can't find it there. It suggests that perhaps there should be a really-truly-absolutely-I-mean-right-now-seq function that evaluates the first argument strictly no matter what (not that this should be something that gets used very frequently). Or are there reasons why this is not feasible?
Sorry to belabor this. Learning to think lazily is IMO one of the hardest aspects of learning Haskell.
Can you clarify what you mean by really-truly-absolutely-I-mean-right-now-seq? The entire specification of seq is in http://haskell.org/onlinereport/basic.html#sect6.2: The function seq is defined by the equations: seq ⊥ b = ⊥ seq a b = b, if a ≠ ⊥ In particular, seq is not defined in terms of evaluation. Even in a lazy model, you cannot assume any *order* of evaluation, only that both arguments will be demanded if the whole expression is. *if* the whole expression is. Seq is uniform - for ALL data types on the lhs, it evaluates it to WHNF (seeing the top constructor or lambda). A recursive seq would not be uniform, and would require a type class or just specialization. If you can see why (x `seq` x) is redundant, you probably understand laziness. Perhaps it would help to see a definition of seq in Haskell? class Eval a where seq :: a -> b -> b instance Eval (a,b) where seq (x,y) b = b instance Eval [a] where seq [] b = b seq (x:xs) b = b instance Eval (Maybe a) where seq Nothing b = b seq (Just x) b = b instance Eval (Either a b) where seq (Left x) b = b seq (Right x) b = b instance Eval Bool where seq True b = b seq False b = b instance Eval Int where ... seq (-1) b = b seq 0 b = b seq 1 b = b ... ? Stefan