r0 :: Strategy a r0 _ = ()Because reduction to WHNF is the default evaluation degree in GpH, a strategy to reduce a value of any type to WHNF is easily defined:
rwhnf :: Strategy a rwhnf x = x `seq` ()
Many expressions can also be reduced to normal form (NF), i.e. a form that contains no redexes, by the rnf strategy. The rnf strategy can be defined over built-in or datatypes, but not over function types or any type incorporating a function type as few reduction engines support the reduction of inner redexes within functions. Rather than defining a new rnfX strategy for each data type X, it is better to have a single overloaded rnf strategy that works on any data type. The obvious solution is to use a Haskell type class, NFData, to overload the rnf operation. Because NF and WHNF coincide for built-in types such as integers and booleans, the default method for rnf is rwhnf.
class NFData a where rnf :: Strategy a rnf = rwhnf
For each data type an instance of NFData must be declared that specifies how to reduce a value of that type to normal form. Such an instance relies on its element types, if any, being in class NFData. Consider lists and pairs for example.
instance NFData a => NFData [a] where rnf [] = () rnf (x:xs) = rnf x `seq` rnf xs instance (NFData a, NFData b) => NFData (a,b) where rnf (x,y) = rnf x `seq` rnf y