ANNOUNCE: deepseq-

Simon Marlow marlowsd at
Wed Nov 18 04:17:31 EST 2009

On 18/11/2009 03:48, Dean Herington wrote:
> At 11:00 AM +0000 11/17/09, Simon Marlow wrote:
>> I've just uploaded deepseq- to Hackage
>> This provides a DeepSeq class with a deepseq method, equivalent to the
>> existing NFData/rnf in the parallel package. I'll be using this in a
>> newly revamped parallel package, which I hope to upload shortly.
>> Cheers,
>> Simon
> The documentation claim that "The default implementation of 'deepseq' is
> simply 'seq'" is not exactly right, as `deepseq` and `seq` have
> different signatures. Which raises the more interesting question: Why
> did you choose a different signature? And, would a version of `seq` with
> the same signature as `deepseq` be useful?

So the main difference is that with the current formulation of deepseq, 
you need to explicitly force the result in order to use it, either with 
a pattern match, another seq, or a pseq.  If we used (a -> b -> b) then 
the top-level forcing is "built-in".

Let's look at an example instance; here (1) is the current deepseq, (2) 
is deepseq :: a -> b -> b

instance (DeepSeq a, DeepSeq b) => DeepSeq (a,b) where
   -- (1) deepseq (a,b) = deepseq a `seq` deepseq b
   -- (2) deepseq (a,b) = deepseq a . deepseq b

They're both fairly similar.  Most instances follow this pattern, with 
seq being replaced by (.).

You could argue that (a -> b -> b) is "doing more" than (a -> ()), 
because it has a kind of built-in continuation (Luke's point).  I buy 
that, although (a -> ()) has a strange-looking unit type in the result 
and you have to use it in conjunction with seq.

(1) generates slightly better code with GHC, because it compiles seq 
directly into a case expression, whereas (.) involves a thunk.  If 
deepseq is inlined all the way down, then it would turn into the same 
thing either way.

I don't feel terribly strongly, but I have a slight preference for the 
current version.


More information about the Libraries mailing list