relude-1.2.2.2: src/Relude/DeepSeq.hs
{-# LANGUAGE Safe #-}
{- |
Module : Relude.DeepSeq
Copyright : (c) 2016 Stephen Diehl
(c) 2016-2018 Serokell
(c) 2018-2023 Kowainik
SPDX-License-Identifier : MIT
Maintainer : Kowainik <xrom.xkov@gmail.com>
Stability : Stable
Portability : Portable
This module contains useful functions to evaluate expressions to weak-head
normal form (WHNF) or just normal form (NF). Useful to force traces or @error@s
inside monadic computations or to remove space leaks.
-}
module Relude.DeepSeq
( -- * "Control.DeepSeq" reexports
NFData (..)
, deepseq
, force
, ($!!)
-- * Evaluation
, evaluateNF
, evaluateNF_
, evaluateWHNF
, evaluateWHNF_
) where
import Control.DeepSeq (NFData (..), deepseq, force, ($!!))
import Relude.Base (IO, seq)
import Relude.Function ((.))
import Relude.Monad (MonadIO, liftIO, (<$!>))
import qualified Control.Exception.Base (evaluate)
-- $setup
-- >>> import Relude
{- | Lifted alias for 'Control.Exception.Base.evaluate' with a clearer name.
>>> let list = [1..5] :: [Int]
>>> :sprint list
list = _
>>> () <$ evaluateWHNF list
>>> :sprint list
list = 1 : _
-}
evaluateWHNF :: MonadIO m => a -> m a
evaluateWHNF = liftIO . Control.Exception.Base.evaluate
{-# INLINE evaluateWHNF #-}
{-# SPECIALIZE evaluateWHNF :: a -> IO a #-}
{- | Like 'evaluateWHNF' but discards value.
>>> let list = [1..5] :: [Int]
>>> :sprint list
list = _
>>> evaluateWHNF_ list
>>> :sprint list
list = 1 : _
-}
evaluateWHNF_ :: MonadIO m => a -> m ()
evaluateWHNF_ what = (`seq` ()) <$!> evaluateWHNF what
{-# INLINE evaluateWHNF_ #-}
{-# SPECIALIZE evaluateWHNF_ :: a -> IO () #-}
{- | Alias for @evaluateWHNF . force@ with a clearer name.
>>> let list = [1..5] :: [Int]
>>> :sprint list
list = _
>>> () <$ evaluateNF list
>>> :sprint list
list = [1,2,3,4,5]
-}
evaluateNF :: (NFData a, MonadIO m) => a -> m a
evaluateNF = evaluateWHNF . force
{-# INLINE evaluateNF #-}
{-# SPECIALIZE evaluateNF :: NFData a => a -> IO a #-}
{- | Alias for @evaluateWHNF . rnf@. Similar to 'evaluateNF'
but discards the resulting value.
>>> let list = [1..5] :: [Int]
>>> :sprint list
list = _
>>> evaluateNF_ list
>>> :sprint list
list = [1,2,3,4,5]
-}
evaluateNF_ :: (NFData a, MonadIO m) => a -> m ()
evaluateNF_ = evaluateWHNF . rnf
{-# INLINE evaluateNF_ #-}
{-# SPECIALIZE evaluateNF_ :: NFData a => a -> IO () #-}