-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | GHC.Generics-based Control.DeepSeq.rnf implementation -- -- This package provides a GHC.Generics-based -- Control.DeepSeq.Generics.genericRnf function which can be used -- for providing a rnf implementation. See the documentation for -- the genericRnf function in the Control.DeepSeq.Generics -- module to get started. -- -- The original idea was pioneered in the generic-deepseq -- package (see -- http://www.haskell.org/pipermail/haskell-cafe/2012-February/099551.html -- for more information). -- -- This package differs from the generic-deepseq package by -- working in combination with the existing deepseq package as -- opposed to defining a conflicting drop-in replacement for -- deepseq's Control.Deepseq module. @package deepseq-generics @version 0.1.0.0 -- | Note: Beyond the primary scope of providing the genericRnf -- helper, this module also re-exports the definitions from -- Control.DeepSeq for convenience. If this poses any problems, -- just use qualified or explicit import statements (see code usage -- example in the genericRnf description) module Control.DeepSeq.Generics -- | GHC.Generics-based rnf implementation -- -- This provides a generic rnf implementation for one type at a -- time. If the type of the value genericRnf is asked to reduce to -- NF contains values of other types, those types have to provide -- NFData instances. This also means that recursive types can only -- be used with genericRnf if a NFData instance has been -- defined as well (see examples below). -- -- The typical usage for genericRnf is for reducing boilerplate -- code when defining NFData instances for ordinary algebraic -- datatypes. See the code below for some simple usage examples: -- --
-- {-# LANGUAGE DeriveGeneric #-}
--
-- import Control.DeepSeq
-- import Control.DeepSeq.Generics (genericRnf)
-- import GHC.Generics
--
-- -- simple record
-- data Foo = Foo AccountId Name Address
-- deriving Generic
--
-- type Address = [String]
-- type Name = String
-- newtype AccountId = AccountId Int
--
-- instance NFData AccountId
-- instance NFData Foo where rnf = genericRnf
--
-- -- recursive list-like type
-- data N = Z | S N deriving Generic
--
-- instance NFData N where rnf = genericRnf
--
-- -- parametric & recursive type
-- data Bar a = Bar0 | Bar1 a | Bar2 (Bar a)
-- deriving Generic
--
-- instance NFData a => NFData (Bar a) where rnf = genericRnf
--
--
-- Note: The GNFData type-class showing up in the type-signature
-- is used internally and not exported on purpose currently.
genericRnf :: (Generic a, GNFData (Rep a)) => a -> ()
-- | deepseq: fully evaluates the first argument, before returning
-- the second.
--
-- The name deepseq is used to illustrate the relationship to
-- seq: where seq is shallow in the sense that it only
-- evaluates the top level of its argument, deepseq traverses the
-- entire data structure evaluating it completely.
--
-- deepseq can be useful for forcing pending exceptions,
-- eradicating space leaks, or forcing lazy I/O to happen. It is also
-- useful in conjunction with parallel Strategies (see the
-- parallel package).
--
-- There is no guarantee about the ordering of evaluation. The
-- implementation may evaluate the components of the structure in any
-- order or in parallel. To impose an actual order on evaluation, use
-- pseq from Control.Parallel in the parallel
-- package.
deepseq :: NFData a => a -> b -> b
-- | a variant of deepseq that is useful in some circumstances:
--
-- -- force x = x `deepseq` x ---- -- force x fully evaluates x, and then returns it. Note -- that force x only performs evaluation when the value of -- force x itself is demanded, so essentially it turns shallow -- evaluation into deep evaluation. force :: NFData a => a -> a -- | A class of types that can be fully evaluated. class NFData a rnf :: NFData a => a -> () -- | the deep analogue of $!. In the expression f $!! x, -- x is fully evaluated before the function f is -- applied to it. ($!!) :: NFData a => (a -> b) -> a -> b instance (GNFData a, GNFData b) => GNFData (a :+: b) instance (GNFData a, GNFData b) => GNFData (a :*: b) instance GNFData a => GNFData (M1 i c a) instance NFData a => GNFData (K1 i a) instance GNFData U1