-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Bounded deepseq, including support for generic deriving -- -- NOTE: Version 0.6.* is a transitional version. Please refer to -- this page for details about what has changed since 0.5.5, -- and what's in store when bump 0.6 to 0.7. -- -- This package provides methods for partially (or fully) evaluating data -- structures ("bounded deep evaluation"). -- -- More information is available on the project homepage. There -- may be activity on this reddit discussion, where your comments -- are invited. -- -- Quoting from the deepseq package: -- -- "Artificial forcing is often used for adding strictness to a -- program, e.g. in order to force pending exceptions, remove space -- leaks, or force lazy IO to happen. It is also useful in parallel -- programs, to ensure work does not migrate to the wrong thread." -- -- Sometimes we don't want to, or cannot, force all the way, for instance -- when dealing with potentially infinite values of coinductive types. -- Also, bounded forcing bridges the theoretical axis between shallow seq -- and full deepseq. -- -- We provide two new classes NFDataN and NFDataP. -- Instances of these provide bounded deep evaluation for arbitrary -- polytypic terms: -- --
-- {-# LANGUAGE TemplateHaskell #-}
-- {-# LANGUAGE DataKinds #-}
-- {-# LANGUAGE TypeFamilies #-}
-- {-# LANGUAGE DeriveDataTypeable #-}
-- {-# LANGUAGE GADTs #-} -- for GHC < 7.8 (== 7.6.3)
--
-- import Generics.SOP.TH
-- import Control.DeepSeq.Bounded.Seqable
--
-- data TA = A1 TB TA | A2
-- data TB = B1 Int | B2 TA
--
-- deriveGeneric ''TA
-- deriveGeneric ''TB
--
-- main = return $! force_ Propagate (A1 (force_ Propagate (B2 undefined)) A2)
--
module Control.DeepSeq.Bounded.Generic.GSeqable
grnf_ :: Generic a => SeqNode -> a -> ()
gseq_ :: Generic a => SeqNode -> a -> b -> b
gforce_ :: Generic a => SeqNode -> a -> a
-- | seqharn x is semantically the same as x,
-- except its strictness, parallellism, etc. can be tweaked
-- dynamically...
--
-- -- seqharn = to . hliftA (gforce_ Insulate) . from ---- -- I can see how this would be useful at compile-time, but how can we -- use this if seqharn only runs post-compilation? Or is it just -- analogous to forcep?... -- -- Also: How exactly to dynamically configure this?... seqharn :: Generic a => a -> a module Control.DeepSeq.Bounded.PatUtil -- | Compute the union of a list of Patterns. -- -- Note that unionPats is undefined when homologous nodes specify -- incompatible arities (only possible when WR or TR are -- involved). -- -- XXX Support for the various attributes is work in progress. -- It may be impossible to arrive at a consistent treatment for all -- attributes under unions. At the last moment, 0.6.0.0 will not -- be supporting type constraints under union, intersection or testing -- subpattern predicate. This is work in progress, but the five -- un-modified W* node types should be safe. unionPats :: [Pattern] -> Pattern -- | Compute the intersection of a list of Patterns. -- -- Where two (or more) homologous WR nodes disagree in arity, the -- intersection at that position becomes WI. -- -- XXX This doesn't yet handle type-constrained PatNodes -- (TI, TR, TN or TW). Other attributes are -- handled in a haphazard fashion. This is work in progress, but the five -- un-modified W* node types should be safe. intersectPats :: [Pattern] -> Pattern -- | Return True if the first pattern matches the second (and -- False otherwise). -- -- Arities must correspond (or the second pattern's node must be wild) -- for the match to succeed at each recursive PatNode -- (i.e. WR or TR). Matching does not imply -- spanning; flip subPat would work for that. -- -- XXX This doesn't yet handle type-constrained PatNodes -- (TI, TR, TN or TW), because -- intersectPats doesn't. Generally speaking, it is difficult to -- arrive at a good policy for subpattern, union and intersection, when -- mixed types of nodes with various attribute values are considered! -- Other attributes are handled in a haphazard fashion. This is work in -- progress, but the five un-modified W* node types should be -- safe. -- -- More formally, we have two "Subpattern Axioms": -- --
-- showPat . compilePat patstring = patstring ---- -- (up to optional whitespace, and canonical ordering of any attributes), -- provided that compilePat patstring succeeds. (And, only up -- to subpatterns elided from # (WI or TI) or from * -- (WW, WN, TW, or TN) nodes, in case these -- are still accepted by the parser!) showPat :: Pattern -> String -- | This module provides an overloaded function, deepseqn, for -- partially (or fully) evaluating data structures to a given depth. module Control.DeepSeq.Bounded.NFDataN -- | deepseqn n x y evaluates x to depth n, before -- returning y. -- -- This is used when expression x also appears in y, -- but mere evaluation of y does not force the embedded -- x subexpression as deeply as we wish. -- -- The name deepseqn 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, deepseqn n -- traverses (evaluates) the entire top n levels of the data -- structure. -- -- A typical 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 values -- of coinductive data types are supported by principled bounding of deep -- evaluation. -- -- It is also useful for diagnostic purposes when trying to understand -- and manipulate space/time trade-offs in lazy code, and as a less -- indiscriminate substitute for deepseq. -- -- Furthermore, deepseqn can sometimes be a better solution than -- using stict fields in your data structures, because the latter will -- behave strictly everywhere that its constructors are used, instead of -- just where its laziness is problematic. -- -- There may be possible applications to the prevention of resource leaks -- in lazy streaming, but I'm not certain. -- -- One of the special qualities of NFDataN is shape oblivity: it -- doesn't care about any details of the shape of the term it's forcing, -- it only cares about stratifying levels of recursion depth. (I would -- say "as contrasted with NFDataP" but cannot, because -- NFDataP was extended to include NFDataN -- syntax/capabilities, precisely to ammend this deficiency.) deepseqn :: NFDataN a => Int -> a -> b -> b -- | forcen is a variant of deepseqn that is useful in some -- circumstances. -- --
-- forcen n x = deepseqn n x x ---- -- forcen n x evaluates x to depth n, and then -- returns it. Recall that, in common with all Haskell functions, -- forcen only performs evaluation when upstream demand actually -- occurs, so essentially it turns shallow evaluation into -- depth-n evaluation. forcen :: NFDataN a => Int -> a -> a -- | A class of types that can be evaluated to arbitrary depth. class NFDataN a where rnfn n x | n <= 0 = () | otherwise = x `seq` () rnfn :: NFDataN a => Int -> a -> () instance (NFDataN a1, NFDataN a2, NFDataN a3, NFDataN a4, NFDataN a5, NFDataN a6, NFDataN a7, NFDataN a8, NFDataN a9) => NFDataN (a1, a2, a3, a4, a5, a6, a7, a8, a9) instance (NFDataN a1, NFDataN a2, NFDataN a3, NFDataN a4, NFDataN a5, NFDataN a6, NFDataN a7, NFDataN a8) => NFDataN (a1, a2, a3, a4, a5, a6, a7, a8) instance (NFDataN a1, NFDataN a2, NFDataN a3, NFDataN a4, NFDataN a5, NFDataN a6, NFDataN a7) => NFDataN (a1, a2, a3, a4, a5, a6, a7) instance (NFDataN a1, NFDataN a2, NFDataN a3, NFDataN a4, NFDataN a5, NFDataN a6) => NFDataN (a1, a2, a3, a4, a5, a6) instance (NFDataN a1, NFDataN a2, NFDataN a3, NFDataN a4, NFDataN a5) => NFDataN (a1, a2, a3, a4, a5) instance (NFDataN a, NFDataN b, NFDataN c, NFDataN d) => NFDataN (a, b, c, d) instance (NFDataN a, NFDataN b, NFDataN c) => NFDataN (a, b, c) instance (NFDataN a, NFDataN b) => NFDataN (a, b) instance (Ix a, NFDataN a, NFDataN b) => NFDataN (Array a b) instance NFDataN a => NFDataN [a] instance NFDataN Version instance (NFDataN a, NFDataN b) => NFDataN (Either a b) instance NFDataN a => NFDataN (Maybe a) instance (RealFloat a, NFDataN a) => NFDataN (Complex a) instance (Integral a, NFDataN a) => NFDataN (Ratio a) instance NFDataN (a -> b) instance NFDataN (Fixed a) instance NFDataN Word64 instance NFDataN Word32 instance NFDataN Word16 instance NFDataN Word8 instance NFDataN Int64 instance NFDataN Int32 instance NFDataN Int16 instance NFDataN Int8 instance NFDataN () instance NFDataN Bool instance NFDataN Char instance NFDataN Double instance NFDataN Float instance NFDataN Integer instance NFDataN Word instance NFDataN Int -- | This module provides generic functions rnf_, force_ and -- seq_, for efficient switching between n=0 and -- n=2 in the corresponding 'rnfn n', 'forcen n' and 'deepseqn -- n' (of NFDataN). This is useful for connecting units of forcing -- (propagating demand). It was motivated for use with -- auto-instrumentation, where seq_ can be injected at every node -- of the AST (refer to the seqaid project). -- -- Each SeqNode carries a couple bits of information, determining -- which depth (0 or 2) is in effect, and whether to spark parallel -- evaluation when the depth is 2. This state can be configured -- statically or dynamically. module Control.DeepSeq.Bounded.Seqable rnf_ :: Generic a => SeqNode -> a -> () force_ :: Generic a => SeqNode -> a -> a seq_ :: Generic a => SeqNode -> a -> b -> b data SeqNode Insulate :: SeqNode Propagate :: SeqNode Spark :: SeqNode -- | Support for generic deriving (via Generics.SOP) of -- NFDataN instances. -- -- NFDataN does not have any superclasses. -- -- It is also possible to derive instances using GHC.Generics, -- which avoids SOP and TH, but if you plan to use NFDataP then -- SOP is required. (SOP can be used without TH if necessary; the -- interested reader is referred to SOP documentation.) -- -- This metaboilerplate is standard for using the generic deriving -- facilities of GHC.Generics and Generics.SOP. Consider -- seqaid for a turnkey solution. -- --
-- {-# LANGUAGE TemplateHaskell #-}
-- {-# LANGUAGE DataKinds #-}
-- {-# LANGUAGE TypeFamilies #-}
-- {-# LANGUAGE DeriveGeneric #-}
-- {-# LANGUAGE GADTs #-} -- for GHC < 7.8 (== 7.6.3)
--
-- import Generics.SOP.TH
-- import Control.DeepSeq.Bounded ( NFDataN(..), grnfn )
-- import GHC.Generics ( Generic )
--
-- import Control.DeepSeq.Bounded ( forcen )
--
-- data TA = A1 TB TA | A2 deriving ( Generic )
-- instance NFDataN TA where rnfn = grnfn
--
-- data TB = B1 Int | B2 TA deriving ( Generic )
-- instance NFDataN TB where rnfn = grnfn
--
-- deriveGeneric ''TA
-- deriveGeneric ''TB
--
-- main = return $! forcen 3 (A1 (B2 undefined) A2)
--
module Control.DeepSeq.Bounded.Generic.GNFDataN
grnfn :: (Generic a, All2 NFDataN (Code a)) => Int -> a -> ()
-- | This module provides an overloaded function, deepseqp, for
-- partially (or fully) evaluating data structures to bounded depth via
-- pattern matching on term shape, and on class, type, and constructor
-- names.
--
-- There are two ways to use this API.
--
-- -- forcep pat x = deepseqp pat x x -- (cannot write x `deepseqp pat` x by analogy with x `deepseq` x) ---- -- forcep pat x evaluates x to the depth determined by -- pat, and then returns x. Again from deepseq: -- "Note that forcep pat x only takes effect when the value -- of forcep pat x itself is demanded, so essentially it turns -- shallow evaluation into evaluation to arbitrary bounded depth." -- -- Composition fuses (see forcep_). forcep :: NFDataP a => String -> a -> a -- | Self-composition fuses via -- --
-- "deepseqp_/composition" -- forall p1 p2 x1 x2. -- (.) (deepseqp_ p2 x2) (deepseqp_ p1 x1) -- = deepseqp_ ( liftPats [p1, p2] ) (x1,x2) ---- -- (Other fusion rules, not yet documented, may also be in effect.) deepseqp_ :: NFDataP a => Pattern -> a -> b -> b -- | Self-composition fuses via -- --
-- "forcep_/composition" -- forall p1 p2 x. -- (.) (forcep_ p2) (forcep_ p1) x -- = forcep_ ( unionPats [p1, p2] ) x ---- -- (Other fusion rules, not yet documented, may also be in effect.) forcep_ :: NFDataP a => Pattern -> a -> a data DeepSeqBounded_PingException DeepSeqBounded_PingException :: String -> DeepSeqBounded_PingException -- | A class of types that can be evaluated over an arbitrary finite -- pattern. class (Typeable a, NFDataN a, NFData a) => NFDataP a where rnfp p x | handleAttrs p x == Node XX [] = undefined rnfp (Node (WI {}) _) _ = () rnfp (Node (TR as) chs) d = if elem td treps then d `seq` () else () where td = show $ typeRepTyCon $ typeOf d treps = typeConstraints as rnfp (Node (TI as) chs) d = if elem td treps then () else d `seq` () where td = show $ typeRepTyCon $ typeOf d treps = typeConstraints as rnfp (Node (TW as) chs) d = if elem td treps then d `seq` () else () where td = show $ typeRepTyCon $ typeOf d treps = typeConstraints as rnfp _ d = d `seq` () rnfp :: NFDataP a => Pattern -> a -> () handleAttrs :: Typeable d => Pattern -> d -> Pattern module Control.DeepSeq.Bounded.NFDataPDyn -- | SOP/SYB hybrid dynamic rnfp. Takes a SYB GenericQ -- PatNode argument, which extends the pattern dynamically, -- depending on the type of the value node. rnfpDyn :: (Generic a, All2 Show (Code a), All2 NFData (Code a), All2 NFDataN (Code a), All2 NFDataP (Code a), All2 Data (Code a)) => (forall c. Data c => c -> PatNode) -> a -> () -- | SOP/SYB hybrid dynamic deepseqp. deepseqpDyn :: (Show a, NFDataP a, Generic a, Data a, All2 Show (Code a), All2 NFData (Code a), All2 NFDataN (Code a), All2 NFDataP (Code a), All2 Data (Code a)) => (forall c. Data c => c -> PatNode) -> a -> b -> b -- | SOP/SYB hybrid dynamic forcep. forcepDyn :: (Show a, NFDataP a, Generic a, Data a, All2 Show (Code a), All2 NFData (Code a), All2 NFDataN (Code a), All2 NFDataP (Code a), All2 Data (Code a)) => (forall c. Data c => c -> PatNode) -> a -> a -- | SOP-only dynamic rnfp. Takes a SOP generic function yielding -- PatNode, which extends the pattern dynamically, depending on -- the type of the value node. rnfpDyn' :: (Generic a, All2 Generic (Code a), All2 Show (Code a), All2 NFData (Code a), All2 NFDataN (Code a), All2 NFDataP (Code a)) => (forall c. Generic c => c -> PatNode) -> a -> () -- | SOP-only dynamic deepseqp. deepseqpDyn' :: (Show a, NFDataP a, Generic a, Data a, All2 Generic (Code a), All2 Show (Code a), All2 NFData (Code a), All2 NFDataN (Code a), All2 NFDataP (Code a)) => (forall c. Generic c => c -> PatNode) -> a -> b -> b -- | SOP-only dynamic forcep. forcepDyn' :: (Show a, NFDataP a, Generic a, Data a, All2 Generic (Code a), All2 Show (Code a), All2 NFData (Code a), All2 NFDataN (Code a), All2 NFDataP (Code a)) => (forall c. Generic c => c -> PatNode) -> a -> a -- | SOP/Typeable hybrid dynamic rnfp. Takes a SYB GenericQ -- PatNode argument, which extends the pattern dynamically, -- depending on the type of the value node. rnfpDyn'' :: (Generic a, All2 Show (Code a), All2 NFData (Code a), All2 NFDataN (Code a), All2 NFDataP (Code a)) => (forall c. Typeable c => c -> PatNode) -> a -> () -- | SOP/Typeable hybrid dynamic deepseqp. deepseqpDyn'' :: (Show a, NFDataP a, Generic a, Data a, All2 Show (Code a), All2 NFData (Code a), All2 NFDataN (Code a), All2 NFDataP (Code a)) => (forall c. Typeable c => c -> PatNode) -> a -> b -> b -- | SOP/Typeable hybrid dynamic forcep. forcepDyn'' :: (Show a, NFDataP a, Generic a, Data a, All2 Show (Code a), All2 NFData (Code a), All2 NFDataN (Code a), All2 NFDataP (Code a)) => (forall c. Typeable c => c -> PatNode) -> a -> a -- | Support for generic deriving (via Generics.SOP) of -- NFDataP instances. -- -- Note that NFDataP has superclasses NFDataN, -- NFData and Typeable. -- -- This metaboilerplate is standard for using the generic deriving -- facilities of GHC.Generics and Generics.SOP. Consider -- seqaid for a turnkey solution. -- --
-- {-# LANGUAGE TemplateHaskell #-}
-- {-# LANGUAGE DataKinds #-}
-- {-# LANGUAGE TypeFamilies #-}
-- {-# LANGUAGE DeriveGeneric #-}
-- {-# LANGUAGE DeriveDataTypeable #-}
-- {-# LANGUAGE GADTs #-} -- for GHC < 7.8 (== 7.6.3)
--
-- import Generics.SOP.TH
-- import Control.DeepSeq.Bounded ( NFDataP(..), grnfp )
-- import Control.DeepSeq.Bounded ( NFDataN(..), grnfn )
-- import Control.DeepSeq.Generics ( NFData(..), genericRnf )
-- import GHC.Generics ( Generic ) -- for deriving NFData
-- import Data.Typeable ( Typeable ) -- for name-constrained pattern nodes
--
-- import Control.DeepSeq.Bounded ( forcep )
--
-- data TA = A1 TB TA | A2 deriving ( Generic, Typeable )
-- instance NFData TA where rnf = genericRnf
-- instance NFDataN TA where rnfn = grnfn
-- instance NFDataP TA where rnfp = grnfp
--
-- data TB = B1 Int | B2 TA deriving ( Generic, Typeable )
-- instance NFData TB where rnf = genericRnf
-- instance NFDataN TB where rnfn = grnfn
-- instance NFDataP TB where rnfp = grnfp
--
-- deriveGeneric ''TA
-- deriveGeneric ''TB
--
-- main = return $! forcep "((!).)" (A1 (B2 undefined) A2)
--
module Control.DeepSeq.Bounded.Generic.GNFDataP
grnfp :: (Generic a, HasDatatypeInfo a, All2 NFDataP (Code a), NFDataP a) => Pattern -> a -> ()
-- | Support for generic deriving (via Generics.SOP) of
-- NFDataN and NFDataP instances. Also, SOP
-- generic functions implementing Seqable without a class and
-- instances.
--
-- This metaboilerplate is standard for using the generic deriving
-- facilities of GHC.Generics and Generics.SOP. Consider
-- seqaid for a turnkey solution.
--
--
-- {-# LANGUAGE TemplateHaskell #-}
-- {-# LANGUAGE DataKinds #-}
-- {-# LANGUAGE TypeFamilies #-}
-- {-# LANGUAGE DeriveGeneric #-}
-- {-# LANGUAGE DeriveDataTypeable #-}
-- {-# LANGUAGE GADTs #-} -- for GHC < 7.8 (== 7.6.3)
--
-- import Generics.SOP.TH
-- import Control.DeepSeq.Bounded ( NFDataN(..), grnfn, NFDataP(..), grnfp )
-- import Control.DeepSeq.Generic ( NFData(..), genericRnf )
-- import GHC.Generics ( Generic ) -- for deriving NFData
-- import Data.Typeable ( Typeable ) -- for name-constrained pattern nodes
-- import Control.DeepSeq.Bounded ( forcen, forcep )
--
-- data TA = A1 TB TA | A2 deriving ( Generic, Typeable )
-- instance NFData TA where rnf = genericRnf
-- instance NFDataN TA where rnfn = grnfn
-- instance NFDataP TA where rnfp = grnfp
--
-- data TB = B1 Int | B2 TA deriving ( Generic, Typeable )
-- instance NFData TB where rnf = genericRnf
-- instance NFDataN TB where rnfn = grnfn
-- instance NFDataP TB where rnfp = grnfp
--
-- deriveGeneric ''TA
-- deriveGeneric ''TB
--
-- main = mainP
-- mainN = return $! forcen 3 (A1 (B2 undefined) A2) :: IO TA
-- mainP = return $! forcep "((!).)" (A1 (B2 undefined) A2) :: IO TA
-- mainS = return $! force_ Propagate (A1 (force_ Propagate (B2 undefined)) A2) :: IO TA
--
module Control.DeepSeq.Bounded.Generic
grnfn :: (Generic a, All2 NFDataN (Code a)) => Int -> a -> ()
grnfp :: (Generic a, HasDatatypeInfo a, All2 NFDataP (Code a), NFDataP a) => Pattern -> a -> ()
grnf_ :: Generic a => SeqNode -> a -> ()
gseq_ :: Generic a => SeqNode -> a -> b -> b
gforce_ :: Generic a => SeqNode -> a -> a
-- | 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.
--
-- Artificial forcing is most commonly used to suppress space leak, but
-- it has many uses besides. Another is to ensure that exceptions hidden
-- within lazy fields of a data structure don't 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, a form of time
-- leak).
--
-- Unlike DeepSeq, potentially infinite values of 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 is also supported (via
-- pseq).
module Control.DeepSeq.Bounded
data Rose a
Node :: a -> [Rose a] -> Rose a
class FF k where data family F k :: * -> *
phi :: (FF k, Generic v, NFDataN v, NFDataP v) => k -> F k v -> v
deepseq_bounded_flag__new_improved_pattern_grammar :: Bool
instance FF Pattern
instance FF Int
instance FF SeqNode