marlowsd at gmail.com
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-184.108.40.206 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.
> 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
More information about the Libraries