planet-mitchell-0.1.0: Planet Mitchell

Eval

Synopsis

seq :: a -> b -> b #

The value of seq a b is bottom if a is bottom, and otherwise equal to b. In other words, it evaluates the first argument a to weak head normal form (WHNF). seq is usually introduced to improve performance by avoiding unneeded laziness.

A note on evaluation order: the expression seq a b does not guarantee that a will be evaluated before b. The only guarantee given by seq is that the both a and b will be evaluated before seq returns a value. In particular, this means that b may be evaluated before a. If you need to guarantee a specific order of evaluation, you must use the function pseq from the "parallel" package.

lazy :: a -> a #

The lazy function restrains strictness analysis a little. The call lazy e means the same as e, but lazy has a magical property so far as strictness analysis is concerned: it is lazy in its first argument, even though its semantics is strict. After strictness analysis has run, calls to lazy are inlined to be the identity function.

This behaviour is occasionally useful when controlling evaluation order. Notably, lazy is used in the library definition of par:

par :: a -> b -> b
par x y = case (par# x) of _ -> lazy y

If lazy were not lazy, par would look strict in y which would defeat the whole purpose of par.

Like seq, the argument of lazy can have an unboxed type.

($!) :: (a -> b) -> a -> b infixr 0 # Strict (call-by-value) application operator. It takes a function and an argument, evaluates the argument to weak head normal form (WHNF), then calls the function with that value. evaluate :: a -> IO a # Evaluate the argument to weak head normal form. evaluate is typically used to uncover any exceptions that a lazy value may contain, and possibly handle them. evaluate only evaluates to weak head normal form. If deeper evaluation is needed, the force function from Control.DeepSeq may be handy: evaluate$ force x

There is a subtle difference between evaluate x and return $! x, analogous to the difference between throwIO and throw. If the lazy value x throws an exception, return$! x will fail to return an IO action and will throw an exception instead. evaluate x, on the other hand, always produces an IO action; that action will throw an exception upon execution iff x throws an exception upon evaluation.

The practical implication of this difference is that due to the imprecise exceptions semantics,

(return $! error "foo") >> error "bar" may throw either "foo" or "bar", depending on the optimizations performed by the compiler. On the other hand, evaluate (error "foo") >> error "bar" is guaranteed to throw "foo". The rule of thumb is to use evaluate to force or handle exceptions in lazy values. If, on the other hand, you are forcing a lazy value for efficiency reasons only and do not care about exceptions, you may use return$! x.

# Normal form

data NF a #

NF is an abstract data type representing data which has been evaluated to normal form. Specifically, if a value of type NF a is in weak head normal form, then it is in reduced normal form; alternatively, it is only necessary to seq an NF a to assure that it is fully evaluated.

Instances
 Eq a => Eq (NF a) Instance detailsDefined in Data.NF.Internal Methods(==) :: NF a -> NF a -> Bool #(/=) :: NF a -> NF a -> Bool # Ord a => Ord (NF a) Instance detailsDefined in Data.NF.Internal Methodscompare :: NF a -> NF a -> Ordering #(<) :: NF a -> NF a -> Bool #(<=) :: NF a -> NF a -> Bool #(>) :: NF a -> NF a -> Bool #(>=) :: NF a -> NF a -> Bool #max :: NF a -> NF a -> NF a #min :: NF a -> NF a -> NF a # NFData (NF a) Instance detailsDefined in Data.NF.Internal Methodsrnf :: NF a -> () #

makeNF :: NFData a => a -> NF a #

Creates a value of type NF. The first time the result is evaluated to whnf, the value will be rnfed. To avoid this rnf, see UnsafeNF.

getNF :: NF a -> a #

Retrieves a from a value of type NF a; this value is guaranteed to be in normal form.

class NFData a where #

A class of types that can be fully evaluated.

Since: deepseq-1.1.0.0

Methods

rnf :: a -> () #

rnf should reduce its argument to normal form (that is, fully evaluate all sub-components), and then return '()'.

### GenericNFData 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 Colour

Starting 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

rnf a = seq a ()

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
 Instance detailsDefined in Control.DeepSeq Methodsrnf :: Bool -> () # Instance detailsDefined in Control.DeepSeq Methodsrnf :: Char -> () # Instance detailsDefined in Control.DeepSeq Methodsrnf :: Double -> () # Instance detailsDefined in Control.DeepSeq Methodsrnf :: Float -> () # Instance detailsDefined in Control.DeepSeq Methodsrnf :: Int -> () # Instance detailsDefined in Control.DeepSeq Methodsrnf :: Int8 -> () # Instance detailsDefined in Control.DeepSeq Methodsrnf :: Int16 -> () # Instance detailsDefined in Control.DeepSeq Methodsrnf :: Int32 -> () # Instance detailsDefined in Control.DeepSeq Methodsrnf :: Int64 -> () # Instance detailsDefined in Control.DeepSeq Methodsrnf :: Integer -> () # Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: Natural -> () # Instance detailsDefined in Control.DeepSeq Methodsrnf :: Ordering -> () # Instance detailsDefined in Control.DeepSeq Methodsrnf :: Word -> () # Instance detailsDefined in Control.DeepSeq Methodsrnf :: Word8 -> () # Instance detailsDefined in Control.DeepSeq Methodsrnf :: Word16 -> () # Instance detailsDefined in Control.DeepSeq Methodsrnf :: Word32 -> () # Instance detailsDefined in Control.DeepSeq Methodsrnf :: Word64 -> () # Since: deepseq-1.4.2.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: CallStack -> () # NFData () Instance detailsDefined in Control.DeepSeq Methodsrnf :: () -> () # NOTE: Only defined for base-4.8.0.0 and laterSince: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: TyCon -> () # Instance detailsDefined in Data.ByteString.Internal Methodsrnf :: ByteString -> () # Instance detailsDefined in Data.ByteString.Lazy.Internal Methodsrnf :: ByteString -> () # Instance detailsDefined in Data.Scientific Methodsrnf :: Scientific -> () # Instance detailsDefined in Data.Time.Clock.Internal.UTCTime Methodsrnf :: UTCTime -> () # Instance detailsDefined in Data.Aeson.Types.Internal Methodsrnf :: JSONPathElement -> () # Instance detailsDefined in Data.Aeson.Types.Internal Methodsrnf :: Value -> () # Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: ThreadId -> () # Defined as rnf = absurd.Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: Void -> () # Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: Unique -> () # Since: deepseq-1.3.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: Version -> () # Since: deepseq-1.4.2.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: ExitCode -> () # NOTE: Only defined for base-4.8.0.0 and laterSince: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: TypeRep -> () # Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: All -> () # Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: Any -> () # Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: CChar -> () # Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: CSChar -> () # Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: CUChar -> () # Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: CShort -> () # Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: CUShort -> () # Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: CInt -> () # Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: CUInt -> () # Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: CLong -> () # Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: CULong -> () # Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: CLLong -> () # Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: CULLong -> () # Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: CBool -> () # Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: CFloat -> () # Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: CDouble -> () # Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: CPtrdiff -> () # Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: CSize -> () # Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: CWchar -> () # Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: CSigAtomic -> () # Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: CClock -> () # Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: CTime -> () # Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: CUSeconds -> () # Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: CSUSeconds -> () # Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: CFile -> () # Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: CFpos -> () # Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: CJmpBuf -> () # Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: CIntPtr -> () # Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: CUIntPtr -> () # Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: CIntMax -> () # Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: CUIntMax -> () # Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: Fingerprint -> () # Since: deepseq-1.4.2.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: SrcLoc -> () # Instance detailsDefined in Data.ByteString.Short.Internal Methodsrnf :: ShortByteString -> () # Instance detailsDefined in Codec.CBOR.Read Methodsrnf :: DeserialiseFailure -> () # Instance detailsDefined in Data.IntSet.Internal Methodsrnf :: IntSet -> () # Instance detailsDefined in Numeric.Half Methodsrnf :: Half -> () # Instance detailsDefined in Text.Megaparsec.Pos Methodsrnf :: Pos -> () # Instance detailsDefined in Text.Megaparsec.Pos Methodsrnf :: InvalidPosException -> () # Instance detailsDefined in Text.Megaparsec.Pos Methodsrnf :: SourcePos -> () # Instance detailsDefined in Data.IntMultiSet Methodsrnf :: IntMultiSet -> () # Instance detailsDefined in Network.URI Methodsrnf :: URI -> () # Instance detailsDefined in Network.URI Methodsrnf :: URIAuth -> () # Instance detailsDefined in Text.PrettyPrint.HughesPJ Methodsrnf :: Doc -> () # Instance detailsDefined in Text.PrettyPrint.Annotated.HughesPJ Methodsrnf :: TextDetails -> () # Instance detailsDefined in Data.Text.Encoding.Error Methodsrnf :: UnicodeException -> () # Instance detailsDefined in Data.Text.Short.Internal Methodsrnf :: ShortText -> () # Instance detailsDefined in Data.Time.LocalTime.Internal.ZonedTime Methodsrnf :: ZonedTime -> () # Instance detailsDefined in Data.Time.LocalTime.Internal.LocalTime Methodsrnf :: LocalTime -> () # Instance detailsDefined in Data.Time.LocalTime.Internal.TimeOfDay Methodsrnf :: TimeOfDay -> () # Instance detailsDefined in Data.Time.LocalTime.Internal.TimeZone Methodsrnf :: TimeZone -> () # Instance detailsDefined in Data.Time.Clock.Internal.UniversalTime Methodsrnf :: UniversalTime -> () # Instance detailsDefined in Data.Time.Clock.Internal.NominalDiffTime Methodsrnf :: NominalDiffTime -> () # Instance detailsDefined in Data.Time.Clock.Internal.DiffTime Methodsrnf :: DiffTime -> () # Instance detailsDefined in Data.Time.Calendar.Days Methodsrnf :: Day -> () # Instance detailsDefined in Data.UUID.Types.Internal Methodsrnf :: UUID -> () # NFData a => NFData [a] Instance detailsDefined in Control.DeepSeq Methodsrnf :: [a] -> () # NFData a => NFData (Maybe a) Instance detailsDefined in Control.DeepSeq Methodsrnf :: Maybe a -> () # NFData a => NFData (Ratio a) Instance detailsDefined in Control.DeepSeq Methodsrnf :: Ratio a -> () # NFData (Ptr a) Since: deepseq-1.4.2.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: Ptr a -> () # NFData (FunPtr a) Since: deepseq-1.4.2.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: FunPtr a -> () # NFData a => NFData (IResult a) Instance detailsDefined in Data.Aeson.Types.Internal Methodsrnf :: IResult a -> () # NFData a => NFData (Result a) Instance detailsDefined in Data.Aeson.Types.Internal Methodsrnf :: Result a -> () # NFData a => NFData (Approximate a) Instance detailsDefined in Data.Approximate.Type Methodsrnf :: Approximate a -> () # NFData (IORef a) NOTE: Only strict in the reference and not the referenced value.Since: deepseq-1.4.2.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: IORef a -> () # NFData a => NFData (Complex a) Instance detailsDefined in Control.DeepSeq Methodsrnf :: Complex a -> () # NFData (Fixed a) Since: deepseq-1.3.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: Fixed a -> () # NFData a => NFData (Min a) Since: deepseq-1.4.2.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: Min a -> () # NFData a => NFData (Max a) Since: deepseq-1.4.2.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: Max a -> () # NFData a => NFData (First a) Since: deepseq-1.4.2.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: First a -> () # NFData a => NFData (Last a) Since: deepseq-1.4.2.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: Last a -> () # NFData m => NFData (WrappedMonoid m) Since: deepseq-1.4.2.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: WrappedMonoid m -> () # NFData a => NFData (Option a) Since: deepseq-1.4.2.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: Option a -> () # Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: StableName a -> () # NFData a => NFData (ZipList a) Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: ZipList a -> () # NFData a => NFData (Identity a) Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: Identity a -> () # NFData a => NFData (First a) Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: First a -> () # NFData a => NFData (Last a) Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: Last a -> () # NFData a => NFData (Dual a) Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: Dual a -> () # NFData a => NFData (Sum a) Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: Sum a -> () # NFData a => NFData (Product a) Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: Product a -> () # NFData a => NFData (Down a) Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: Down a -> () # NFData (MVar a) NOTE: Only strict in the reference and not the referenced value.Since: deepseq-1.4.2.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: MVar a -> () # NFData a => NFData (NonEmpty a) Since: deepseq-1.4.2.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: NonEmpty a -> () # NFData s => NFData (CI s) Instance detailsDefined in Data.CaseInsensitive.Internal Methodsrnf :: CI s -> () # NFData (Dict c) Instance detailsDefined in Data.Constraint Methodsrnf :: Dict c -> () # NFData a => NFData (IntMap a) Instance detailsDefined in Data.IntMap.Internal Methodsrnf :: IntMap a -> () # NFData a => NFData (SCC a) Instance detailsDefined in Data.Graph Methodsrnf :: SCC a -> () # NFData a => NFData (Tree a) Instance detailsDefined in Data.Tree Methodsrnf :: Tree a -> () # NFData a => NFData (Seq a) Instance detailsDefined in Data.Sequence.Internal Methodsrnf :: Seq a -> () # NFData a => NFData (FingerTree a) Instance detailsDefined in Data.Sequence.Internal Methodsrnf :: FingerTree a -> () # NFData a => NFData (Digit a) Instance detailsDefined in Data.Sequence.Internal Methodsrnf :: Digit a -> () # NFData a => NFData (Node a) Instance detailsDefined in Data.Sequence.Internal Methodsrnf :: Node a -> () # NFData a => NFData (Elem a) Instance detailsDefined in Data.Sequence.Internal Methodsrnf :: Elem a -> () # NFData a => NFData (Set a) Instance detailsDefined in Data.Set.Internal Methodsrnf :: Set a -> () # NFData a => NFData (DList a) Instance detailsDefined in Data.DList Methodsrnf :: DList a -> () # NFData a => NFData (Hashed a) Instance detailsDefined in Data.Hashable.Class Methodsrnf :: Hashed a -> () # NFData (Vector a) Instance detailsDefined in Data.Vector.Primitive Methodsrnf :: Vector a -> () # NFData (Vector a) Instance detailsDefined in Data.Vector.Storable Methodsrnf :: Vector a -> () # NFData (Vector a) Instance detailsDefined in Data.Vector.Unboxed.Base Methodsrnf :: Vector a -> () # NFData a => NFData (HashSet a) Instance detailsDefined in Data.HashSet Methodsrnf :: HashSet a -> () # NFData a => NFData (Vector a) Instance detailsDefined in Data.Vector Methodsrnf :: Vector a -> () # NFData a => NFData (Log a) Instance detailsDefined in Numeric.Log Methodsrnf :: Log a -> () # NFData t => NFData (ErrorItem t) Instance detailsDefined in Text.Megaparsec.Error Methodsrnf :: ErrorItem t -> () # NFData a => NFData (ErrorFancy a) Instance detailsDefined in Text.Megaparsec.Error Methodsrnf :: ErrorFancy a -> () # NFData s => NFData (State s) Instance detailsDefined in Text.Megaparsec.State Methodsrnf :: State s -> () # NFData a => NFData (MultiSet a) Instance detailsDefined in Data.MultiSet Methodsrnf :: MultiSet a -> () # NFData (NF a) Instance detailsDefined in Data.NF.Internal Methodsrnf :: NF a -> () # NFData a => NFData (Doc a) Instance detailsDefined in Text.PrettyPrint.Annotated.HughesPJ Methodsrnf :: Doc a -> () # NFData a => NFData (AnnotDetails a) Instance detailsDefined in Text.PrettyPrint.Annotated.HughesPJ Methodsrnf :: AnnotDetails a -> () # NFData (a -> b) This instance is for convenience and consistency with seq. This assumes that WHNF is equivalent to NF for functions.Since: deepseq-1.3.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: (a -> b) -> () # (NFData a, NFData b) => NFData (Either a b) Instance detailsDefined in Control.DeepSeq Methodsrnf :: Either a b -> () # (NFData a, NFData b) => NFData (a, b) Instance detailsDefined in Control.DeepSeq Methodsrnf :: (a, b) -> () # (NFData k, NFData v) => NFData (HashMap k v) Instance detailsDefined in Data.HashMap.Base Methodsrnf :: HashMap k v -> () # (NFData k, NFData a) => NFData (Map k a) Instance detailsDefined in Data.Map.Internal Methodsrnf :: Map k a -> () # (NFData a, NFData b) => NFData (Array a b) Instance detailsDefined in Control.DeepSeq Methodsrnf :: Array a b -> () # (NFData a, NFData b) => NFData (Arg a b) Since: deepseq-1.4.2.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: Arg a b -> () # NFData (Proxy a) Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: Proxy a -> () # NFData (STRef s a) NOTE: Only strict in the reference and not the referenced value.Since: deepseq-1.4.2.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: STRef s a -> () # a => NFData (a :- b) Instance detailsDefined in Data.Constraint Methodsrnf :: (a :- b) -> () # (NFData a, NFData b) => NFData (Gr a b) Instance detailsDefined in Data.Graph.Inductive.PatriciaTree Methodsrnf :: Gr a b -> () # (NFData a, NFData b) => NFData (Heap a b) Instance detailsDefined in Data.Graph.Inductive.Internal.Heap Methodsrnf :: Heap a b -> () # (NFData t, NFData e) => NFData (ParseError t e) Instance detailsDefined in Text.Megaparsec.Error Methodsrnf :: ParseError t e -> () # (NFData p, NFData v) => NFData (IntPSQ p v) Instance detailsDefined in Data.IntPSQ.Internal Methodsrnf :: IntPSQ p v -> () # (NFData k, NFData v) => NFData (Leaf k v) Instance detailsDefined in Data.HashMap.Base Methodsrnf :: Leaf k v -> () # NFData (MVector s a) Instance detailsDefined in Data.Vector.Unboxed.Base Methodsrnf :: MVector s a -> () # NFData (MVector s a) Instance detailsDefined in Data.Vector.Storable.Mutable Methodsrnf :: MVector s a -> () # NFData (MVector s a) Instance detailsDefined in Data.Vector.Primitive.Mutable Methodsrnf :: MVector s a -> () # (NFData a1, NFData a2, NFData a3) => NFData (a1, a2, a3) Instance detailsDefined in Control.DeepSeq Methodsrnf :: (a1, a2, a3) -> () # NFData a => NFData (Const a b) Since: deepseq-1.4.0.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: Const a b -> () # NFData (a :~: b) Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: (a :~: b) -> () # (NFData k, NFData p, NFData v) => NFData (Bucket k p v) Instance detailsDefined in Data.HashPSQ.Internal Methodsrnf :: Bucket k p v -> () # (NFData k, NFData p, NFData v) => NFData (LTree k p v) Instance detailsDefined in Data.OrdPSQ.Internal Methodsrnf :: LTree k p v -> () # (NFData k, NFData p, NFData v) => NFData (Elem k p v) Instance detailsDefined in Data.OrdPSQ.Internal Methodsrnf :: Elem k p v -> () # (NFData p, NFData k, NFData v) => NFData (HashPSQ k p v) Instance detailsDefined in Data.HashPSQ.Internal Methodsrnf :: HashPSQ k p v -> () # (NFData k, NFData p, NFData v) => NFData (OrdPSQ k p v) Instance detailsDefined in Data.OrdPSQ.Internal Methodsrnf :: OrdPSQ k p v -> () # NFData b => NFData (Tagged s b) Instance detailsDefined in Data.Tagged Methodsrnf :: Tagged s b -> () # (NFData a1, NFData a2, NFData a3, NFData a4) => NFData (a1, a2, a3, a4) Instance detailsDefined in Control.DeepSeq Methodsrnf :: (a1, a2, a3, a4) -> () # (NFData1 f, NFData1 g, NFData a) => NFData (Product f g a) Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: Product f g a -> () # (NFData1 f, NFData1 g, NFData a) => NFData (Sum f g a) Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: Sum f g a -> () # NFData (a :~~: b) Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: (a :~~: b) -> () # (NFData a1, NFData a2, NFData a3, NFData a4, NFData a5) => NFData (a1, a2, a3, a4, a5) Instance detailsDefined in Control.DeepSeq Methodsrnf :: (a1, a2, a3, a4, a5) -> () # (NFData1 f, NFData1 g, NFData a) => NFData (Compose f g a) Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq Methodsrnf :: Compose f g a -> () # (NFData a1, NFData a2, NFData a3, NFData a4, NFData a5, NFData a6) => NFData (a1, a2, a3, a4, a5, a6) Instance detailsDefined in Control.DeepSeq Methodsrnf :: (a1, a2, a3, a4, a5, a6) -> () # (NFData a1, NFData a2, NFData a3, NFData a4, NFData a5, NFData a6, NFData a7) => NFData (a1, a2, a3, a4, a5, a6, a7) Instance detailsDefined in Control.DeepSeq Methodsrnf :: (a1, a2, a3, a4, a5, a6, a7) -> () # (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) Instance detailsDefined in Control.DeepSeq Methodsrnf :: (a1, a2, a3, a4, a5, a6, a7, a8) -> () # (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) Instance detailsDefined in Control.DeepSeq Methodsrnf :: (a1, a2, a3, a4, a5, a6, a7, a8, a9) -> () #

deepseq :: NFData a => a -> b -> b #

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

force :: NFData a => a -> a #

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 h Since: deepseq-1.2.0.0 ($!!) :: NFData a => (a -> b) -> a -> b infixr 0 #

the deep analogue of $!. In the expression f$!! x, x is fully evaluated before the function f is applied to it.

Since: deepseq-1.2.0.0

(<$!!>) :: (Monad m, NFData b) => (a -> b) -> m a -> m b infixl 4 # Deeply strict version of <$>.

Since: deepseq-1.4.3.0

rwhnf :: a -> () #

Reduce to weak head normal form

Equivalent to \x -> seq x ().

Useful for defining NFData for types for which NF=WHNF holds.

data T = C1 | C2 | C3
instance NFData T where rnf = rwhnf

Since: deepseq-1.4.3.0

class NFData1 (f :: * -> *) where #

A class of functors that can be fully evaluated.

Since: deepseq-1.4.3.0

Methods

liftRnf :: (a -> ()) -> f a -> () #

liftRnf should reduce its argument to normal form (that is, fully evaluate all sub-components), given an argument to reduce a arguments, and then return '()'.

See rnf for the generic deriving.

Instances
 NFData1 [] Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a -> ()) -> [a] -> () # Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a -> ()) -> Maybe a -> () # Available on base >=4.9Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a -> ()) -> Ratio a -> () # Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a -> ()) -> Ptr a -> () # Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a -> ()) -> FunPtr a -> () # Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a -> ()) -> IORef a -> () # Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a -> ()) -> Fixed a -> () # Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a -> ()) -> Min a -> () # Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a -> ()) -> Max a -> () # Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a -> ()) -> First a -> () # Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a -> ()) -> Last a -> () # Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a -> ()) -> WrappedMonoid a -> () # Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a -> ()) -> Option a -> () # Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a -> ()) -> StableName a -> () # Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a -> ()) -> ZipList a -> () # Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a -> ()) -> Identity a -> () # Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a -> ()) -> First a -> () # Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a -> ()) -> Last a -> () # Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a -> ()) -> Dual a -> () # Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a -> ()) -> Sum a -> () # Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a -> ()) -> Product a -> () # Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a -> ()) -> Down a -> () # Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a -> ()) -> MVar a -> () # Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a -> ()) -> NonEmpty a -> () # NFData a => NFData1 (Either a) Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a0 -> ()) -> Either a a0 -> () # NFData a => NFData1 ((,) a) Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a0 -> ()) -> (a, a0) -> () # NFData a => NFData1 (Array a) Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a0 -> ()) -> Array a a0 -> () # NFData a => NFData1 (Arg a) Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a0 -> ()) -> Arg a a0 -> () # NFData1 (Proxy :: * -> *) Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a -> ()) -> Proxy a -> () # NFData1 (STRef s) Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a -> ()) -> STRef s a -> () # (NFData a1, NFData a2) => NFData1 ((,,) a1 a2) Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a -> ()) -> (a1, a2, a) -> () # NFData a => NFData1 (Const a :: * -> *) Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a0 -> ()) -> Const a a0 -> () # NFData1 ((:~:) a) Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a0 -> ()) -> (a :~: a0) -> () # (NFData a1, NFData a2, NFData a3) => NFData1 ((,,,) a1 a2 a3) Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a -> ()) -> (a1, a2, a3, a) -> () # (NFData1 f, NFData1 g) => NFData1 (Product f g) Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a -> ()) -> Product f g a -> () # (NFData1 f, NFData1 g) => NFData1 (Sum f g) Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a -> ()) -> Sum f g a -> () # NFData1 ((:~~:) a :: * -> *) Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a0 -> ()) -> (a :~~: a0) -> () # (NFData a1, NFData a2, NFData a3, NFData a4) => NFData1 ((,,,,) a1 a2 a3 a4) Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a -> ()) -> (a1, a2, a3, a4, a) -> () # (NFData1 f, NFData1 g) => NFData1 (Compose f g) Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a -> ()) -> Compose f g a -> () # (NFData a1, NFData a2, NFData a3, NFData a4, NFData a5) => NFData1 ((,,,,,) a1 a2 a3 a4 a5) Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a -> ()) -> (a1, a2, a3, a4, a5, a) -> () # (NFData a1, NFData a2, NFData a3, NFData a4, NFData a5, NFData a6) => NFData1 ((,,,,,,) a1 a2 a3 a4 a5 a6) Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a -> ()) -> (a1, a2, a3, a4, a5, a6, a) -> () # (NFData a1, NFData a2, NFData a3, NFData a4, NFData a5, NFData a6, NFData a7) => NFData1 ((,,,,,,,) a1 a2 a3 a4 a5 a6 a7) Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a -> ()) -> (a1, a2, a3, a4, a5, a6, a7, a) -> () # (NFData a1, NFData a2, NFData a3, NFData a4, NFData a5, NFData a6, NFData a7, NFData a8) => NFData1 ((,,,,,,,,) a1 a2 a3 a4 a5 a6 a7 a8) Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf :: (a -> ()) -> (a1, a2, a3, a4, a5, a6, a7, a8, a) -> () #

rnf1 :: (NFData1 f, NFData a) => f a -> () #

Lift the standard rnf function through the type constructor.

Since: deepseq-1.4.3.0

class NFData2 (p :: * -> * -> *) where #

A class of bifunctors that can be fully evaluated.

Since: deepseq-1.4.3.0

Minimal complete definition

liftRnf2

Methods

liftRnf2 :: (a -> ()) -> (b -> ()) -> p a b -> () #

liftRnf2 should reduce its argument to normal form (that is, fully evaluate all sub-components), given functions to reduce a and b arguments respectively, and then return '()'.

Note: Unlike for the unary liftRnf, there is currently no support for generically deriving liftRnf2.

Instances
 Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf2 :: (a -> ()) -> (b -> ()) -> Either a b -> () # Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf2 :: (a -> ()) -> (b -> ()) -> (a, b) -> () # Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf2 :: (a -> ()) -> (b -> ()) -> Array a b -> () # Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf2 :: (a -> ()) -> (b -> ()) -> Arg a b -> () # Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf2 :: (a -> ()) -> (b -> ()) -> STRef a b -> () # NFData a1 => NFData2 ((,,) a1) Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf2 :: (a -> ()) -> (b -> ()) -> (a1, a, b) -> () # NFData2 (Const :: * -> * -> *) Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf2 :: (a -> ()) -> (b -> ()) -> Const a b -> () # NFData2 ((:~:) :: * -> * -> *) Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf2 :: (a -> ()) -> (b -> ()) -> (a :~: b) -> () # (NFData a1, NFData a2) => NFData2 ((,,,) a1 a2) Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf2 :: (a -> ()) -> (b -> ()) -> (a1, a2, a, b) -> () # NFData2 ((:~~:) :: * -> * -> *) Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf2 :: (a -> ()) -> (b -> ()) -> (a :~~: b) -> () # (NFData a1, NFData a2, NFData a3) => NFData2 ((,,,,) a1 a2 a3) Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf2 :: (a -> ()) -> (b -> ()) -> (a1, a2, a3, a, b) -> () # (NFData a1, NFData a2, NFData a3, NFData a4) => NFData2 ((,,,,,) a1 a2 a3 a4) Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf2 :: (a -> ()) -> (b -> ()) -> (a1, a2, a3, a4, a, b) -> () # (NFData a1, NFData a2, NFData a3, NFData a4, NFData a5) => NFData2 ((,,,,,,) a1 a2 a3 a4 a5) Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf2 :: (a -> ()) -> (b -> ()) -> (a1, a2, a3, a4, a5, a, b) -> () # (NFData a1, NFData a2, NFData a3, NFData a4, NFData a5, NFData a6) => NFData2 ((,,,,,,,) a1 a2 a3 a4 a5 a6) Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf2 :: (a -> ()) -> (b -> ()) -> (a1, a2, a3, a4, a5, a6, a, b) -> () # (NFData a1, NFData a2, NFData a3, NFData a4, NFData a5, NFData a6, NFData a7) => NFData2 ((,,,,,,,,) a1 a2 a3 a4 a5 a6 a7) Since: deepseq-1.4.3.0 Instance detailsDefined in Control.DeepSeq MethodsliftRnf2 :: (a -> ()) -> (b -> ()) -> (a1, a2, a3, a4, a5, a6, a7, a, b) -> () #

rnf2 :: (NFData2 p, NFData a, NFData b) => p a b -> () #

Lift the standard rnf function through the type constructor.

Since: deepseq-1.4.3.0

# Evaluation strategies

data Eval a #

Eval is a Monad that makes it easier to define parallel strategies. It is a strict identity monad: that is, in

m >>= f

m is evaluated before the result is passed to f.

instance Monad Eval where
return  = Done
m >>= k = case m of
Done x -> k x

If you wanted to construct a Strategy for a pair that sparked the first component in parallel and then evaluated the second component, you could write

myStrat :: Strategy (a,b)
myStrat (a,b) = do { a' <- rpar a; b' <- rseq b; return (a',b') }

Alternatively, you could write this more compactly using the Applicative style as

myStrat (a,b) = (,) <$> rpar a <*> rseq b Instances  Instance detailsDefined in Control.Parallel.Strategies Methods(>>=) :: Eval a -> (a -> Eval b) -> Eval b #(>>) :: Eval a -> Eval b -> Eval b #return :: a -> Eval a #fail :: String -> Eval a # Instance detailsDefined in Control.Parallel.Strategies Methodsfmap :: (a -> b) -> Eval a -> Eval b #(<$) :: a -> Eval b -> Eval a # Instance detailsDefined in Control.Parallel.Strategies Methodsmfix :: (a -> Eval a) -> Eval a # Instance detailsDefined in Control.Parallel.Strategies Methodspure :: a -> Eval a #(<*>) :: Eval (a -> b) -> Eval a -> Eval b #liftA2 :: (a -> b -> c) -> Eval a -> Eval b -> Eval c #(*>) :: Eval a -> Eval b -> Eval b #(<*) :: Eval a -> Eval b -> Eval a #

runEval :: Eval a -> a #

Pull the result out of the monad.

type Strategy a = a -> Eval a #

A Strategy is a function that embodies a parallel evaluation strategy. The function traverses (parts of) its argument, evaluating subexpressions in parallel or in sequence.

A Strategy may do an arbitrary amount of evaluation of its argument, but should not return a value different from the one it was passed.

Parallel computations may be discarded by the runtime system if the program no longer requires their result, which is why a Strategy function returns a new value equivalent to the old value. The intention is that the program applies the Strategy to a structure, and then uses the returned value, discarding the old value. This idiom is expressed by the using function.

using :: a -> Strategy a -> a infixl 0 #

Evaluate a value using the given Strategy.

x using s = runEval (s x)

withStrategy :: Strategy a -> a -> a #

evaluate a value using the given Strategy. This is simply using with the arguments reversed.

dot :: Strategy a -> Strategy a -> Strategy a infixr 9 #

Compose two strategies sequentially. This is the analogue to function composition on strategies.

For any strategies strat1, strat2, and strat3,

(strat1 dot strat2) dot strat3 == strat1 dot (strat2 dot strat3)
strat1 dot strat1 = strat1
strat1 dot r0 == strat1
strat2 dot strat1 == strat2 . withStrategy strat1

rseq evaluates its argument to weak head normal form.

rseq == evalSeq Control.Seq.rseq

rdeepseq :: NFData a => Strategy a #

rdeepseq fully evaluates its argument.

rdeepseq == evalSeq Control.Seq.rdeepseq

evalTraversable :: Traversable t => Strategy a -> Strategy (t a) #

Evaluate the elements of a traversable data structure according to the given strategy.

evalList :: Strategy a -> Strategy [a] #

Evaluate each element of a list according to the given strategy. Equivalent to evalTraversable at the list type.

evalTuple2 :: Strategy a -> Strategy b -> Strategy (a, b) #

evalTuple3 :: Strategy a -> Strategy b -> Strategy c -> Strategy (a, b, c) #

evalTuple4 :: Strategy a -> Strategy b -> Strategy c -> Strategy d -> Strategy (a, b, c, d) #

evalTuple5 :: Strategy a -> Strategy b -> Strategy c -> Strategy d -> Strategy e -> Strategy (a, b, c, d, e) #

evalTuple6 :: Strategy a -> Strategy b -> Strategy c -> Strategy d -> Strategy e -> Strategy f -> Strategy (a, b, c, d, e, f) #

evalTuple7 :: Strategy a -> Strategy b -> Strategy c -> Strategy d -> Strategy e -> Strategy f -> Strategy g -> Strategy (a, b, c, d, e, f, g) #

evalTuple8 :: Strategy a -> Strategy b -> Strategy c -> Strategy d -> Strategy e -> Strategy f -> Strategy g -> Strategy h -> Strategy (a, b, c, d, e, f, g, h) #

evalTuple9 :: Strategy a -> Strategy b -> Strategy c -> Strategy d -> Strategy e -> Strategy f -> Strategy g -> Strategy h -> Strategy i -> Strategy (a, b, c, d, e, f, g, h, i) #