| Copyright | (c) 2016 Stephen Diehl (c) 2016-2018 Serokell (c) 2018-2023 Kowainik  | 
|---|---|
| License | MIT | 
| Maintainer | Kowainik <xrom.xkov@gmail.com> | 
| Stability | Stable | 
| Portability | Portable | 
| Safe Haskell | Safe | 
| Language | Haskell2010 | 
Relude.DeepSeq
Contents
- Control.DeepSeq reexports
 - Evaluation
 
Description
This module contains useful functions to evaluate expressions to weak-head
normal form (WHNF) or just normal form (NF). Useful to force traces or errors
inside monadic computations or to remove space leaks.
Synopsis
- class NFData a where
- rnf :: a -> ()
 
 - deepseq :: NFData a => a -> b -> b
 - force :: NFData a => a -> a
 - ($!!) :: NFData a => (a -> b) -> a -> b
 - evaluateNF :: (NFData a, MonadIO m) => a -> m a
 - evaluateNF_ :: (NFData a, MonadIO m) => a -> m ()
 - evaluateWHNF :: MonadIO m => a -> m a
 - evaluateWHNF_ :: MonadIO m => a -> m ()
 
Control.DeepSeq reexports
A class of types that can be fully evaluated.
Since: deepseq-1.1.0.0
Minimal complete definition
Nothing
Methods
rnf should reduce its argument to normal form (that is, fully
 evaluate all sub-components), and then return ().
Generic NFData deriving
Starting with GHC 7.2, you can automatically derive instances
 for types possessing a Generic instance.
Note: Generic1 can be auto-derived starting with GHC 7.4
{-# LANGUAGE DeriveGeneric #-}
import GHC.Generics (Generic, Generic1)
import Control.DeepSeq
data Foo a = Foo a String
             deriving (Eq, Generic, Generic1)
instance NFData a => NFData (Foo a)
instance NFData1 Foo
data Colour = Red | Green | Blue
              deriving Generic
instance NFData ColourStarting with GHC 7.10, the example above can be written more
 concisely by enabling the new DeriveAnyClass extension:
{-# LANGUAGE DeriveGeneric, DeriveAnyClass #-}
import GHC.Generics (Generic)
import Control.DeepSeq
data Foo a = Foo a String
             deriving (Eq, Generic, Generic1, NFData, NFData1)
data Colour = Red | Green | Blue
              deriving (Generic, NFData)
Compatibility with previous deepseq versions
Prior to version 1.4.0.0, the default implementation of the rnf
 method was defined as
rnfa =seqa ()
However, starting with deepseq-1.4.0.0, the default
 implementation is based on DefaultSignatures allowing for
 more accurate auto-derived NFData instances. If you need the
 previously used exact default rnf method implementation
 semantics, use
instance NFData Colour where rnf x = seq x ()
or alternatively
instance NFData Colour where rnf = rwhnf
or
{-# LANGUAGE BangPatterns #-}
instance NFData Colour where rnf !_ = ()Instances
| NFData ByteArray | Since: deepseq-1.4.7.0  | 
Defined in Control.DeepSeq  | |
| NFData All | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData Any | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData TypeRep | NOTE: Prior to  Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData Unique | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData Version | Since: deepseq-1.3.0.0  | 
Defined in Control.DeepSeq  | |
| NFData CBool | Since: deepseq-1.4.3.0  | 
Defined in Control.DeepSeq  | |
| NFData CChar | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData CClock | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData CDouble | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData CFile | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData CFloat | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData CFpos | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData CInt | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData CIntMax | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData CIntPtr | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData CJmpBuf | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData CLLong | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData CLong | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData CPtrdiff | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData CSChar | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData CSUSeconds | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq Methods rnf :: CSUSeconds -> () #  | |
| NFData CShort | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData CSigAtomic | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq Methods rnf :: CSigAtomic -> () #  | |
| NFData CSize | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData CTime | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData CUChar | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData CUInt | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData CUIntMax | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData CUIntPtr | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData CULLong | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData CULong | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData CUSeconds | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData CUShort | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData CWchar | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData Void | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData ThreadId | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData Fingerprint | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq Methods rnf :: Fingerprint -> () #  | |
| NFData MaskingState | Since: deepseq-1.4.4.0  | 
Defined in Control.DeepSeq Methods rnf :: MaskingState -> () #  | |
| NFData ExitCode | Since: deepseq-1.4.2.0  | 
Defined in Control.DeepSeq  | |
| NFData Int16 | |
Defined in Control.DeepSeq  | |
| NFData Int32 | |
Defined in Control.DeepSeq  | |
| NFData Int64 | |
Defined in Control.DeepSeq  | |
| NFData Int8 | |
Defined in Control.DeepSeq  | |
| NFData CallStack | Since: deepseq-1.4.2.0  | 
Defined in Control.DeepSeq  | |
| NFData SrcLoc | Since: deepseq-1.4.2.0  | 
Defined in Control.DeepSeq  | |
| NFData Word16 | |
Defined in Control.DeepSeq  | |
| NFData Word32 | |
Defined in Control.DeepSeq  | |
| NFData Word64 | |
Defined in Control.DeepSeq  | |
| NFData Word8 | |
Defined in Control.DeepSeq  | |
| NFData ByteString | |
Defined in Data.ByteString.Internal.Type Methods rnf :: ByteString -> () #  | |
| NFData ByteString | |
Defined in Data.ByteString.Lazy.Internal Methods rnf :: ByteString -> () #  | |
| NFData ShortByteString | |
Defined in Data.ByteString.Short.Internal Methods rnf :: ShortByteString -> () #  | |
| NFData IntSet | |
Defined in Data.IntSet.Internal  | |
| NFData OsChar | |
Defined in System.OsString.Internal.Types.Hidden  | |
| NFData OsString | |
Defined in System.OsString.Internal.Types.Hidden  | |
| NFData PosixChar | |
Defined in System.OsString.Internal.Types.Hidden  | |
| NFData PosixString | |
Defined in System.OsString.Internal.Types.Hidden Methods rnf :: PosixString -> () #  | |
| NFData WindowsChar | |
Defined in System.OsString.Internal.Types.Hidden Methods rnf :: WindowsChar -> () #  | |
| NFData WindowsString | |
Defined in System.OsString.Internal.Types.Hidden Methods rnf :: WindowsString -> () #  | |
| NFData Module | Since: deepseq-1.4.8.0  | 
Defined in Control.DeepSeq  | |
| NFData Ordering | |
Defined in Control.DeepSeq  | |
| NFData TyCon | NOTE: Prior to  Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData OsChar | |
Defined in System.OsString.Internal.Types  | |
| NFData OsString | |
Defined in System.OsString.Internal.Types  | |
| NFData PosixChar | |
Defined in System.OsString.Internal.Types  | |
| NFData PosixString | |
Defined in System.OsString.Internal.Types Methods rnf :: PosixString -> () #  | |
| NFData WindowsChar | |
Defined in System.OsString.Internal.Types Methods rnf :: WindowsChar -> () #  | |
| NFData WindowsString | |
Defined in System.OsString.Internal.Types Methods rnf :: WindowsString -> () #  | |
| NFData TextDetails | |
Defined in Text.PrettyPrint.Annotated.HughesPJ Methods rnf :: TextDetails -> () #  | |
| NFData Doc | |
Defined in Text.PrettyPrint.HughesPJ  | |
| NFData UnicodeException | |
Defined in Data.Text.Encoding.Error Methods rnf :: UnicodeException -> () #  | |
| NFData Integer | |
Defined in Control.DeepSeq  | |
| NFData Natural | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData () | |
Defined in Control.DeepSeq  | |
| NFData Bool | |
Defined in Control.DeepSeq  | |
| NFData Char | |
Defined in Control.DeepSeq  | |
| NFData Double | |
Defined in Control.DeepSeq  | |
| NFData Float | |
Defined in Control.DeepSeq  | |
| NFData Int | |
Defined in Control.DeepSeq  | |
| NFData Word | |
Defined in Control.DeepSeq  | |
| NFData a => NFData (ZipList a) | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData (MutableByteArray s) | Since: deepseq-1.4.8.0  | 
Defined in Control.DeepSeq Methods rnf :: MutableByteArray s -> () #  | |
| NFData a => NFData (Complex a) | |
Defined in Control.DeepSeq  | |
| NFData a => NFData (Identity a) | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData a => NFData (First a) | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData a => NFData (Last a) | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData a => NFData (Down a) | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData a => NFData (First a) | Since: deepseq-1.4.2.0  | 
Defined in Control.DeepSeq  | |
| NFData a => NFData (Last a) | Since: deepseq-1.4.2.0  | 
Defined in Control.DeepSeq  | |
| NFData a => NFData (Max a) | Since: deepseq-1.4.2.0  | 
Defined in Control.DeepSeq  | |
| NFData a => NFData (Min a) | Since: deepseq-1.4.2.0  | 
Defined in Control.DeepSeq  | |
| NFData m => NFData (WrappedMonoid m) | Since: deepseq-1.4.2.0  | 
Defined in Control.DeepSeq Methods rnf :: WrappedMonoid m -> () #  | |
| NFData a => NFData (Dual a) | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData a => NFData (Product a) | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData a => NFData (Sum a) | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData a => NFData (NonEmpty a) | Since: deepseq-1.4.2.0  | 
Defined in Control.DeepSeq  | |
| NFData (IORef a) | NOTE: Only strict in the reference and not the referenced value. Since: deepseq-1.4.2.0  | 
Defined in Control.DeepSeq  | |
| NFData (MVar a) | NOTE: Only strict in the reference and not the referenced value. Since: deepseq-1.4.2.0  | 
Defined in Control.DeepSeq  | |
| NFData (FunPtr a) | Since: deepseq-1.4.2.0  | 
Defined in Control.DeepSeq  | |
| NFData (Ptr a) | Since: deepseq-1.4.2.0  | 
Defined in Control.DeepSeq  | |
| NFData a => NFData (Ratio a) | |
Defined in Control.DeepSeq  | |
| NFData (StableName a) | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq Methods rnf :: StableName a -> () #  | |
| NFData a => NFData (SCC a) | |
Defined in Data.Graph  | |
| NFData a => NFData (IntMap a) | |
Defined in Data.IntMap.Internal  | |
| NFData a => NFData (Digit a) | |
Defined in Data.Sequence.Internal  | |
| NFData a => NFData (Elem a) | |
Defined in Data.Sequence.Internal  | |
| NFData a => NFData (FingerTree a) | |
Defined in Data.Sequence.Internal Methods rnf :: FingerTree a -> () #  | |
| NFData a => NFData (Node a) | |
Defined in Data.Sequence.Internal  | |
| NFData a => NFData (Seq a) | |
Defined in Data.Sequence.Internal  | |
| NFData a => NFData (Set a) | |
Defined in Data.Set.Internal  | |
| NFData a => NFData (Tree a) | |
| NFData a => NFData (Hashed a) | |
Defined in Data.Hashable.Class  | |
| NFData a => NFData (AnnotDetails a) | |
Defined in Text.PrettyPrint.Annotated.HughesPJ Methods rnf :: AnnotDetails a -> () #  | |
| NFData a => NFData (Doc a) | |
Defined in Text.PrettyPrint.Annotated.HughesPJ  | |
| NFData a => NFData (Array a) | |
Defined in Data.HashMap.Internal.Array  | |
| NFData a => NFData (HashSet a) | |
Defined in Data.HashSet.Internal  | |
| NFData a => NFData (Maybe a) | |
Defined in Control.DeepSeq  | |
| NFData a => NFData (Solo a) | Since: deepseq-1.4.6.0  | 
Defined in Control.DeepSeq  | |
| NFData a => NFData [a] | |
Defined in Control.DeepSeq  | |
| (NFData a, NFData b) => NFData (Either a b) | |
Defined in Control.DeepSeq  | |
| NFData (Fixed a) | Since: deepseq-1.3.0.0  | 
Defined in Control.DeepSeq  | |
| NFData (Proxy a) | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| (NFData a, NFData b) => NFData (Arg a b) | Since: deepseq-1.4.2.0  | 
Defined in Control.DeepSeq  | |
| NFData (TypeRep a) | Since: deepseq-1.4.8.0  | 
Defined in Control.DeepSeq  | |
| (NFData a, NFData b) => NFData (Array a b) | |
Defined in Control.DeepSeq  | |
| NFData (STRef s a) | NOTE: Only strict in the reference and not the referenced value. Since: deepseq-1.4.2.0  | 
Defined in Control.DeepSeq  | |
| (NFData k, NFData a) => NFData (Map k a) | |
Defined in Data.Map.Internal  | |
| (NFData k, NFData v) => NFData (HashMap k v) | |
Defined in Data.HashMap.Internal  | |
| (NFData k, NFData v) => NFData (Leaf k v) | |
Defined in Data.HashMap.Internal  | |
| (NFData a, NFData b) => NFData (a, b) | |
Defined in Control.DeepSeq  | |
| NFData (a -> b) | This instance is for convenience and consistency with  Since: deepseq-1.3.0.0  | 
Defined in Control.DeepSeq  | |
| NFData a => NFData (Const a b) | Since: deepseq-1.4.0.0  | 
Defined in Control.DeepSeq  | |
| NFData (a :~: b) | Since: deepseq-1.4.3.0  | 
Defined in Control.DeepSeq  | |
| (NFData a1, NFData a2, NFData a3) => NFData (a1, a2, a3) | |
Defined in Control.DeepSeq  | |
| (NFData (f a), NFData (g a)) => NFData (Product f g a) | Note: in  Since: deepseq-1.4.3.0  | 
Defined in Control.DeepSeq  | |
| (NFData (f a), NFData (g a)) => NFData (Sum f g a) | Note: in  Since: deepseq-1.4.3.0  | 
Defined in Control.DeepSeq  | |
| NFData (a :~~: b) | Since: deepseq-1.4.3.0  | 
Defined in Control.DeepSeq  | |
| (NFData a1, NFData a2, NFData a3, NFData a4) => NFData (a1, a2, a3, a4) | |
Defined in Control.DeepSeq  | |
| NFData (f (g a)) => NFData (Compose f g a) | Note: in  Since: deepseq-1.4.3.0  | 
Defined in Control.DeepSeq  | |
| (NFData a1, NFData a2, NFData a3, NFData a4, NFData a5) => NFData (a1, a2, a3, a4, a5) | |
Defined in Control.DeepSeq  | |
| (NFData a1, NFData a2, NFData a3, NFData a4, NFData a5, NFData a6) => NFData (a1, a2, a3, a4, a5, a6) | |
Defined in Control.DeepSeq  | |
| (NFData a1, NFData a2, NFData a3, NFData a4, NFData a5, NFData a6, NFData a7) => NFData (a1, a2, a3, a4, a5, a6, a7) | |
Defined in Control.DeepSeq  | |
| (NFData a1, NFData a2, NFData a3, NFData a4, NFData a5, NFData a6, NFData a7, NFData a8) => NFData (a1, a2, a3, a4, a5, a6, a7, a8) | |
Defined in Control.DeepSeq  | |
| (NFData a1, NFData a2, NFData a3, NFData a4, NFData a5, NFData a6, NFData a7, NFData a8, NFData a9) => NFData (a1, a2, a3, a4, a5, a6, a7, a8, a9) | |
Defined in Control.DeepSeq  | |
deepseq :: NFData a => a -> b -> b infixr 0 #
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.
Since: deepseq-1.1.0.0
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 can be conveniently used in combination with ViewPatterns:
{-# LANGUAGE BangPatterns, ViewPatterns #-}
import Control.DeepSeq
someFun :: ComplexData -> SomeResult
someFun (force -> !arg) = {- 'arg' will be fully evaluated -}Another useful application is to combine force with
 evaluate in order to force deep evaluation
 relative to other IO operations:
import Control.Exception (evaluate)
import Control.DeepSeq
main = do
  result <- evaluate $ force $ pureComputation
  {- 'result' will be fully evaluated at this point -}
  return ()Finally, here's an exception safe variant of the readFile' example:
readFile' :: FilePath -> IO String
readFile' fn = bracket (openFile fn ReadMode) hClose $ \h ->
                       evaluate . force =<< hGetContents hSince: deepseq-1.2.0.0
($!!) :: NFData a => (a -> b) -> a -> b infixr 0 #
The deep analogue of $!.  f $!! x fully evaluates x
 before returning f x.
There is no guarantee about the ordering of evaluation.
 f x may be evaluated before x is fully evaluated.
 To impose an actual order on evaluation, use pseq from
 Control.Parallel in the parallel package.
Since: deepseq-1.2.0.0
Evaluation
evaluateNF :: (NFData a, MonadIO m) => a -> m a Source #
Alias for evaluateWHNF . force with a clearer name.
>>>let list = [1..5] :: [Int]>>>:sprint listlist = _>>>() <$ evaluateNF list>>>:sprint listlist = [1,2,3,4,5]
evaluateNF_ :: (NFData a, MonadIO m) => a -> m () Source #
Alias for evaluateWHNF . rnf. Similar to evaluateNF
but discards the resulting value.
>>>let list = [1..5] :: [Int]>>>:sprint listlist = _>>>evaluateNF_ list>>>:sprint listlist = [1,2,3,4,5]
evaluateWHNF :: MonadIO m => a -> m a Source #
Lifted alias for evaluate with a clearer name.
>>>let list = [1..5] :: [Int]>>>:sprint listlist = _>>>() <$ evaluateWHNF list>>>:sprint listlist = 1 : _
evaluateWHNF_ :: MonadIO m => a -> m () Source #
Like evaluateWHNF but discards value.
>>>let list = [1..5] :: [Int]>>>:sprint listlist = _>>>evaluateWHNF_ list>>>:sprint listlist = 1 : _