# [Haskell-cafe] problem with IO, strictness, and "let"

Michael Vanier mvanier at cs.caltech.edu
Fri Jul 13 20:20:05 EDT 2007

```Stefan,

What I meant by really-truly-absolutely-I-mean-right-now-seq is something that would evaluate its
argument as far as it is possible to do so i.e. something that forces strict evaluation of an
argument.  That's what I thought seq did, but now I see I was wrong; it only "goes one deep" as it
were.  In fact, as you say, seq is not defined in terms of evaluation; all that it guarantees is
that its first argument is either (a) bottom, in which the result of the entire seq is bottom, or
(b) not bottom.  To do so it has to evaluate the first argument only far enough to show bottom-ness
or not, which is not strict evaluation as I understand it.  So am I right in saying that Haskell has
no way to force strict evaluation?  Or am I confused as to the correct definition of "strict"?

Mike

Stefan O'Rear wrote:
> On Fri, Jul 13, 2007 at 04:29:12PM -0700, Michael Vanier wrote:
>> Albert,
>>
>> 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
```