deepseq-bounded-0.5.0: src/Control/DeepSeq/Bounded.hs
-------------------------------------------------------------------------------
{- LANGUAGE CPP #-}
-------------------------------------------------------------------------------
-- |
-- Module : Control.DeepSeq.Bounded
-- Copyright : (c) 2014, Andrew G. Seniuk
-- License : BSD-style (see the file LICENSE)
--
-- Maintainer : Andrew Seniuk <rasfar@gmail.com>
-- 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(..)
-- * 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
-- * Forced evaluation "molecular style"
, module Control.DeepSeq.Bounded.Seqable
#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
-------------------------------------------------------------------------------