deepseq-bounded-0.6.0.2: Bounded deepseq, including support for generic deriving

CopyrightAndrew G. Seniuk 2014-2015
LicenseBSD-style (see the file LICENSE)
MaintainerAndrew Seniuk <rasfar@gmail.com>
Stabilityprovisional
Portabilityportable
Safe HaskellNone
LanguageHaskell2010

Control.DeepSeq.Bounded.NFDataN

Contents

Description

This module provides an overloaded function, deepseqn, for partially (or fully) evaluating data structures to a given depth.

Synopsis

Depth-bounded analogues of deepseq and force

deepseqn :: NFDataN a => Int -> a -> b -> b Source

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.)

forcen :: NFDataN a => Int -> a -> a Source

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.

Class of things that can be evaluated to an arbitrary finite depth

class NFDataN a where Source

A class of types that can be evaluated to arbitrary depth.

Minimal complete definition

Nothing

Methods

rnfn :: Int -> a -> () Source

Instances

NFDataN Bool 
NFDataN Char 
NFDataN Double 
NFDataN Float 
NFDataN Int 
NFDataN Int8 
NFDataN Int16 
NFDataN Int32 
NFDataN Int64 
NFDataN Integer 
NFDataN Word 
NFDataN Word8 
NFDataN Word16 
NFDataN Word32 
NFDataN Word64 
NFDataN () 
NFDataN Version 
NFDataN a => NFDataN [a] 
(Integral a, NFDataN a) => NFDataN (Ratio a) 
NFDataN a => NFDataN (Maybe a) 
NFDataN (Fixed a) 
(RealFloat a, NFDataN a) => NFDataN (Complex a) 
NFDataN (a -> b) 
(NFDataN a, NFDataN b) => NFDataN (Either a b) 
(NFDataN a, NFDataN b) => NFDataN (a, b) 
(Ix a, NFDataN a, NFDataN b) => NFDataN (Array a b) 
(NFDataN a, NFDataN b, NFDataN c) => NFDataN (a, b, c) 
(NFDataN a, NFDataN b, NFDataN c, NFDataN d) => NFDataN (a, b, c, d) 
(NFDataN a1, NFDataN a2, NFDataN a3, NFDataN a4, NFDataN a5) => NFDataN (a1, a2, a3, a4, a5) 
(NFDataN a1, NFDataN a2, NFDataN a3, NFDataN a4, NFDataN a5, NFDataN a6) => NFDataN (a1, a2, a3, a4, a5, a6) 
(NFDataN a1, NFDataN a2, NFDataN a3, NFDataN a4, NFDataN a5, NFDataN a6, NFDataN a7) => NFDataN (a1, a2, a3, a4, a5, a6, a7) 
(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) 
(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)