------------------------------------------------------------------------------- {- LANGUAGE CPP #-} ------------------------------------------------------------------------------- -- | -- Module : Control.DeepSeq.Bounded -- Copyright : (c) 2014, Andrew G. Seniuk -- License : BSD-style (see the file LICENSE) -- -- Maintainer : Andrew Seniuk -- Stability : provisional -- Portability : portable (but GHC for a few modules using generics) -- -- We provide forcing functions which take a non-strict value -- of a datatype, and force its evaluation in a pricipled way. -- As with 'NFData', one should bear in mind the difference -- between forcing and demand: in order for your forcing to -- take effect, demand must be placed on the forcing function -- itself by the course of execution. -- -- A typical use of bounded forcing is to prevent resource leaks in -- lazy streaming, by forcing chunks of data of bounded but sufficient -- depth for the consumer to make progress. -- -- Another use is to ensure any exceptions hidden within lazy -- fields of a data structure do not leak outside the scope of the -- exception handler; another is to force evaluation of a data structure in -- one thread, before passing it to another thread (preventing work moving -- to the wrong threads). Unlike "DeepSeq", potentially infinite coinductive -- data types are supported by principled bounding of deep evaluation. -- -- Refer to comments in the 'deepseq' package for more information on how -- artificial forcing can be useful. -- -- Recently, control (static or dynamic) of parallelisation has been added. -- Control of evaluation order should also be possible (using 'pseq'). ------------------------------------------------------------------------------- module Control.DeepSeq.Bounded ( -- * Forced evaluation to an arbitrary finite depth #if 1 module Control.DeepSeq.Bounded.NFDataN #else NFDataN(..) , deepseqn, forcen #endif -- * Forced evaluation over a pattern (arbitrary finite, or dynamic) , module Control.DeepSeq.Bounded.Pattern , module Control.DeepSeq.Bounded.PatAlg -- re-exports the former , module Control.DeepSeq.Bounded.NFDataP -- re-exports both #if USE_SOP , module Control.DeepSeq.Bounded.NFDataPDyn -- re-exps. all 3 above #endif -- XXX On second thoughts, I don't want to depend on containers -- package just to provide a rose tree data type!... -- I don't export Data.Tree; ideally the API would never -- require the user to work at that low level, but if -- necessary they can import Data.Tree themselves. , Rose(..) -- * Forced evaluation "molecular style" , module Control.DeepSeq.Bounded.Seqable -- * Generic deriving support via "Generics.SOP" #if USE_SOP , module Control.DeepSeq.Bounded.Generics.GSeqable #endif , module Control.DeepSeq.Bounded.Generics.GNFDataN #if USE_SOP , module Control.DeepSeq.Bounded.Generics.GNFDataP #endif #if USE_WW_DEEPSEQ -- * Re-exported , module Control.DeepSeq #endif ) where ------------------------------------------------------------------------------- import Control.DeepSeq.Bounded.Seqable import Control.DeepSeq.Bounded.NFDataN import Control.DeepSeq.Bounded.Pattern import Control.DeepSeq.Bounded.PatAlg import Control.DeepSeq.Bounded.NFDataP #if USE_SOP import Control.DeepSeq.Bounded.NFDataPDyn #endif -- In its own category, relative to GNFDataN and GNFDataP. #if USE_SOP import Control.DeepSeq.Bounded.Generics.GSeqable #endif import Control.DeepSeq.Bounded.Generics.GNFDataN #if USE_SOP import Control.DeepSeq.Bounded.Generics.GNFDataP #endif #if USE_WW_DEEPSEQ import Control.DeepSeq #endif -------------------------------------------------------------------------------