
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.