-- | Turn a function lazy in its arguments -- into a function strict in its arguments. -- -- It should be noted that this does nothing to change -- the internals of a function. If the function is lazy -- on the inside, these combinators cannot fix that. -- They only change the external entry point to the function: -- the indicated number of arguments will be forced -- before attempting to evaluate the function. -- -- For finer control over evaluation strategies, -- use the @parallel@ package. module Control.Strictly ( -- * Weak Head Normal Form strictly1, strictly2, strictly3, -- * Normal Form veryStrictly1, veryStrictly2, veryStrictly3, ) where import Control.DeepSeq (NFData, deepseq) infixl 0 `strictly1` infixl 0 `veryStrictly1` -- | Equivalent to @$!@ -- -- @strictly1@ is idempotent. -- -- > strictly1 (strictly1 f) x ≡ strictly1 f x strictly1 :: (a -> b) -> a -> b strictly1 f = \a -> a `seq` f a {-# INLINE strictly1 #-} strictly2 :: (a -> b -> c) -> a -> b -> c strictly2 f = \a b -> a `seq` b `seq` f a b {-# INLINE strictly2 #-} strictly3 :: (a -> b -> c -> d) -> a -> b -> c -> d strictly3 f = \a b c -> a `seq` b `seq` c `seq` f a b c {-# INLINE strictly3 #-} -- | Equivalent to @$!!@ -- -- @veryStrictly1@ is idempotent. -- -- > veryStrictly1 (veryStrictly1 f) x ≡ veryStrictly1 f x veryStrictly1 :: (NFData a) => (a -> b) -> a -> b veryStrictly1 f = \a -> a `deepseq` f a {-# INLINE veryStrictly1 #-} veryStrictly2 :: (NFData a, NFData b) => (a -> b -> c) -> a -> b -> c veryStrictly2 f = \a b -> a `deepseq` b `deepseq` f a b {-# INLINE veryStrictly2 #-} veryStrictly3 :: (NFData a, NFData b, NFData c) => (a -> b -> c -> d) -> a -> b -> c -> d veryStrictly3 f = \a b c -> a `deepseq` b `deepseq` c `deepseq` f a b c {-# INLINE veryStrictly3 #-}