nf-1.0.0.3: Data/NF.hs
{-# LANGUAGE CPP #-}
#if __GLASGOW_HASKELL__ >= 704
{-# LANGUAGE Safe #-}
#endif
-----------------------------------------------------------------------------
-- |
-- Module : Data.NF
-- Copyright : (c) Stanford University 2015
-- License : BSD-style (see the file LICENSE)
--
-- Maintainer : ezyang@cs.stanford.edu
-- Stability : experimental
-- Portability : portable
--
-- This module provides a data type, 'NF', representing data which has
-- been evaluated to \"Normal Form\". This is a useful type discipline
-- for many situations when normal form data is necessary, e.g. when
-- transmitting data to other threads over channels. If a library
-- that you are using has the following type:
--
-- @
-- strictWriteChan :: 'NFData' a => 'Control.Concurrent.Chan' a -> a -> 'IO' ()
-- @
--
-- you can specialize it to the following type in order to avoid the
-- cost of repeatedly 'deepseq'ing a value when it is not necessary:
--
-- @
-- strictWriteChan_ :: 'Control.Concurrent.Chan' ('NF' a) -> 'NF' a -> 'IO' ()
-- strictWriteChan_ = strictWriteChan
-- @
--
-- You should also consider providing APIs which only accept 'NF'
-- values, to prevent users from accidentally 'deepseq'ing.
module Data.NF (
NF,
makeNF, getNF,
) where
import Control.DeepSeq
import Data.NF.Internal
-- | Creates a value of type 'NF'. The first time the result is
-- evaluated to whnf, the value will be 'rnf'ed. To avoid this
-- 'rnf', see 'UnsafeNF'.
makeNF :: NFData a => a -> NF a
makeNF x = x `deepseq` UnsafeNF x
-- | Retrieves @a@ from a value of type @'NF' a@; this value
-- is guaranteed to be in normal form.
getNF :: NF a -> a
getNF (UnsafeNF a) = a