Deepseq proposed patch

Julian Blake Kongslie jblake at omgwallhack.org
Thu Jun 10 16:39:08 EDT 2010


Control.DeepSeq has a large number of instances for its class NFData,
I'd like to propose a new one:

import Data.Data

dataDeepSeq :: (Data a) => a -> a
dataDeepSeq a = gmapQr ($) a (seq . dataDeepSeq) a

instance (Data a) => NFData a where
   rnf a = dataDeepSeq a `seq` ()

This is obviously a very broad instance. I believe, for example, that it
correctly covers at least every type that is covered by just the
instances currently provided in Control.DeepSeq. It also makes it easy
to make a new type "deepseq-able" in GHC, as there is an extension which
makes Data derivable. I do not believe this instance to be particularly
inefficient, although I will grant that there may be types where the
NFData instance can force evaluations in a particular order which may be
faster than the order chosen by the Data instance.

The mechanism is relatively straightforward: The gmapQr is recursively
finding all children in the data structure, and creating a long string
of seq calls to force each one to be evaluated before finally returning
the parent structure. As long as the Data instances don't have "holes"
where they skip some children of the structure, this should visit every
thunk in the structure and evaluate them all.

Of course, this raises an interesting point: Are there types which can
be reasonably made NFData instances, but not Data instances, or for
which the NFData instance can be made significantly better in some way?

I'd appreciate your thoughts on this,

-Julian Blake Kongslie
Please CC me on replies.


More information about the Libraries mailing list