Using DeepSeq for exception ordering

Simon Hengel sol at
Wed Nov 7 14:49:21 CET 2012

I'm puzzled whether it is feasible to use existing NFData instances for
exception ordering.

Here is some code that won't work:

    return $!! 'a' : throw exceptionA
    throwIO exceptionB

Here GHC makes a non-deterministic choice between exceptionA and
exceptionB.  The reason is that the standard DeepSeq instances use
`seq`, and `seq` does not help with exception ordering**.

I tried several things (ghc-7.4.2 with -O2), and the following seems to
order the exceptions for this particular case:

    (evaluate . force) ('a' : throw exceptionA)
    throwIO exceptionB

But I'm a little bit worried that this may not hold in general, e.g.

    (return $!! 'a' : throw exceptionA) >>= evaluate
    throwIO exceptionB

results in exceptionB.  I think my main issue here is that I do not
properly understand how seq and seq# (which is used by evaluate) do
interact with each other.  And how I can reason about code that uses

The question is really whether it is "somehow" feasible to use existing
NFData instances to order exceptions.  Or would we need to define a
separate type class + instances for that, e.g.:

    class DeepEvaluate a where
      deepEvaluate :: a -> IO a
      deepEvaluate = evaluate

    instance DeepEvaluate Char where

    instance DeepEvaluate a => DeepEvaluate [a] where
      deepEvaluate = mapM deepEvaluate

If you have any related ideas or thoughts, I'd love to hear about them.


** This is desired behavior, see the discussion at

More information about the Glasgow-haskell-users mailing list