instant-deepseq-0.2: src/lib/Generics/Instant/Functions/DeepSeq.hs
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE UndecidableInstances #-}
module Generics.Instant.Functions.DeepSeq
( -- $defaults
grnfDefault
, RepGNFData
-- * Internals
, GNFData(..)
) where
import Control.DeepSeq (NFData(rnf))
import Generics.Instant
--------------------------------------------------------------------------------
-- $defaults
--
-- You can use 'grnfDefault' as your generic 'rnf' for any 'Representable' type
-- as follows:
--
-- @
-- instance 'NFData' MyType where rnf = 'grnfDefault'
-- @
grnfDefault :: (Representable a, GNFData (Rep a)) => a -> ()
grnfDefault = \a -> grnf (from a)
{-# INLINABLE grnfDefault #-}
-- | @'RepGNFData'@ is simply a synonym for
-- @('Representable' a, 'GNFData' ('Rep' a))@ with the convenient
-- kind @(* -> 'GHC.Exts.Constraint')@
class (Representable a, GNFData (Rep a)) => RepGNFData a
instance (Representable a, GNFData (Rep a)) => RepGNFData a
--------------------------------------------------------------------------------
class GNFData a where
grnf :: a -> ()
instance GNFData Z where
grnf _ = error
"Generics.Instant.Functions.DeepSeq.GNFData Z grnf - impossible"
instance GNFData U where
grnf !U = ()
{-# INLINABLE grnf #-}
instance GNFData a => GNFData (CEq c p q a) where
grnf !(C a) = grnf a `seq` ()
{-# INLINABLE grnf #-}
instance (GNFData a, GNFData b) => GNFData (a :*: b) where
grnf !(a :*: b) = grnf a `seq` grnf b `seq` ()
{-# INLINABLE grnf #-}
instance (GNFData a, GNFData b) => GNFData (a :+: b) where
grnf !(L a) = grnf a `seq` ()
grnf !(R b) = grnf b `seq` ()
{-# INLINABLE grnf #-}
instance NFData a => GNFData (Var a) where
grnf !(Var a) = rnf a `seq` ()
{-# INLINABLE grnf #-}
instance NFData a => GNFData (Rec a) where
grnf !(Rec a) = rnf a `seq` ()
{-# INLINABLE grnf #-}